From b8a69f07771b141303d5cf6fa36cc4a5b3806789 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 27 Sep 2012 15:22:20 +0200 Subject: [PATCH] Adjusting layers pane only when necessary We only want to adjust things that have to do with rendering (like the position of the layers panel) when actually rendering. The handleXChange methods may be called more times than we can actually render, so we never want to do anything that touches the DOM there. Instead, we have to keep track of the state at previous render and adjust the layers panel (or other) based on changes only when rendering. --- src/ol/renderer/dom/map.js | 87 ++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/src/ol/renderer/dom/map.js b/src/ol/renderer/dom/map.js index f1a6f893fd..c2d7ab11e2 100644 --- a/src/ol/renderer/dom/map.js +++ b/src/ol/renderer/dom/map.js @@ -40,10 +40,22 @@ ol.renderer.dom.Map = function(container, map) { this.layerPanes_ = {}; /** - * @type {ol.Coordinate|undefined} + * @type {ol.Coordinate} * @private */ - this.renderedCenter_ = undefined; + this.renderedCenter_ = null; + + /** + * @type {number | undefined} + * @private + */ + this.renderedResolution_ = undefined; + + /** + * @type {ol.Size} + * @private + */ + this.renderedSize_ = null; /** * The pixel offset of the layers pane with respect to its container. @@ -90,13 +102,6 @@ ol.renderer.dom.Map.prototype.handleCenterChanged = function() { if (!map.isDef()) { return; } - // FIXME: shiftLayersPane_ and resetLayersPane_ should be called - // elsewhere as we may be frozen here - if (goog.isDef(this.renderedCenter_)) { - this.shiftLayersPane_(); - } else { - this.resetLayersPane_(); - } map.render(); }; @@ -110,9 +115,6 @@ ol.renderer.dom.Map.prototype.handleResolutionChanged = function() { if (!map.isDef()) { return; } - // FIXME: resetLayersPane_ should be called - // elsewhere as we may be frozen here - this.resetLayersPane_(); map.render(); }; @@ -126,13 +128,55 @@ ol.renderer.dom.Map.prototype.handleSizeChanged = function() { if (!map.isDef()) { return; } - // FIXME: resetLayersPane_ should be called - // elsewhere as we may be frozen here - this.resetLayersPane_(); map.render(); }; +/** + * Render the map. Sets up the layers pane on first render and adjusts its + * position as needed on subsequent calls. + * + * @return {boolean} Animating. + */ +ol.renderer.dom.Map.prototype.render = function() { + var map = this.getMap(); + if (!map.isDef()) { + return false; + } + + var mapSize = map.getSize(); + var mapResolution = map.getResolution(); + var mapCenter = map.getCenter(); + goog.asserts.assert(goog.isDefAndNotNull(mapSize)); + goog.asserts.assert(goog.isDef(mapResolution)); + goog.asserts.assert(goog.isDefAndNotNull(mapCenter)); + + if (goog.isNull(this.renderedCenter_)) { + // first rendering + goog.asserts.assert(!goog.isDef(this.renderedResolution_)); + goog.asserts.assert(goog.isNull(this.renderedSize_)); + this.resetLayersPane_(); + } else { + goog.asserts.assert(goog.isDef(this.renderedResolution_)); + goog.asserts.assert(!goog.isNull(this.renderedSize_)); + if (mapResolution !== this.renderedResolution_ || + !mapSize.equals(this.renderedSize_)) { + // resolution or size changed, adjust layers pane + this.resetLayersPane_(); + } else if (!mapCenter.equals(this.renderedCenter_)) { + // same resolution and size, new center + this.shiftLayersPane_(); + } + } + + this.renderedCenter_ = mapCenter; + this.renderedResolution_ = mapResolution; + this.renderedSize_ = mapSize; + + return goog.base(this, 'render'); +}; + + /** * Reset the layers pane to its initial position. * @private @@ -140,19 +184,7 @@ ol.renderer.dom.Map.prototype.handleSizeChanged = function() { ol.renderer.dom.Map.prototype.resetLayersPane_ = function() { var offset = new ol.Coordinate(0, 0); goog.style.setPosition(this.layersPane_, offset); - this.layersPaneOffset_ = offset; - this.renderedCenter_ = this.map.getCenter(); - - this.setOrigin_(); -}; - - -/** - * Set the origin for each layer renderer. - * @private - */ -ol.renderer.dom.Map.prototype.setOrigin_ = function() { var center = this.map.getCenter(); var resolution = this.map.getResolution(); var mapSize = this.map.getSize(); @@ -182,6 +214,5 @@ ol.renderer.dom.Map.prototype.shiftLayersPane_ = function() { offset.x += Math.round((oldCenter.x - center.x) / resolution); offset.y += Math.round((center.y - oldCenter.y) / resolution); goog.style.setPosition(this.layersPane_, offset); - this.renderedCenter_ = center; } };