From 11ec1de89b5421e2e84aa3cc9c50b4df99c65fa1 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 15 Jan 2013 20:47:25 +0100 Subject: [PATCH 1/2] Refactor mouse position control to use postrender event --- examples/side-by-side.js | 4 +- src/objectliterals.exports | 2 +- src/ol/control/mousepositioncontrol.js | 131 +++++++++---------------- 3 files changed, 51 insertions(+), 86 deletions(-) diff --git a/examples/side-by-side.js b/examples/side-by-side.js index d92105bec0..540a277e76 100644 --- a/examples/side-by-side.js +++ b/examples/side-by-side.js @@ -43,7 +43,7 @@ domMap.getControls().push(new ol.control.MousePosition({ coordinateFormat: ol.Coordinate.toStringHDMS, projection: ol.Projection.getFromCode('EPSG:4326'), target: document.getElementById('domMousePosition'), - undefinedHtml: ' ' + undefinedHTML: ' ' })); var webglMap = new ol.Map({ @@ -59,7 +59,7 @@ webglMap.getControls().push(new ol.control.MousePosition({ coordinateFormat: ol.Coordinate.toStringHDMS, projection: ol.Projection.getFromCode('EPSG:4326'), target: document.getElementById('webglMousePosition'), - undefinedHtml: ' ' + undefinedHTML: ' ' })); var keyboardInteraction = new ol.interaction.Keyboard(); diff --git a/src/objectliterals.exports b/src/objectliterals.exports index fcda1d5bdb..9ba2c520b3 100644 --- a/src/objectliterals.exports +++ b/src/objectliterals.exports @@ -7,7 +7,7 @@ @exportObjectLiteralProperty ol.control.MousePositionOptions.map ol.Map|undefined @exportObjectLiteralProperty ol.control.MousePositionOptions.projection ol.Projection|undefined @exportObjectLiteralProperty ol.control.MousePositionOptions.target Element|undefined -@exportObjectLiteralProperty ol.control.MousePositionOptions.undefinedHtml string|undefined +@exportObjectLiteralProperty ol.control.MousePositionOptions.undefinedHTML string|undefined @exportObjectLiteral ol.control.ZoomOptions @exportObjectLiteralProperty ol.control.ZoomOptions.delta number|undefined diff --git a/src/ol/control/mousepositioncontrol.js b/src/ol/control/mousepositioncontrol.js index 653baac95d..1d2fff1669 100644 --- a/src/ol/control/mousepositioncontrol.js +++ b/src/ol/control/mousepositioncontrol.js @@ -3,6 +3,7 @@ goog.provide('ol.control.MousePosition'); +goog.require('goog.dom'); goog.require('goog.events'); goog.require('goog.events.EventType'); goog.require('goog.style'); @@ -48,52 +49,51 @@ ol.control.MousePosition = function(mousePositionOptions) { * @private * @type {string} */ - this.undefinedHtml_ = goog.isDef(mousePositionOptions.undefinedHtml) ? - mousePositionOptions.undefinedHtml : ''; + this.undefinedHTML_ = goog.isDef(mousePositionOptions.undefinedHTML) ? + mousePositionOptions.undefinedHTML : ''; /** * @private - * @type {ol.TransformFunction} + * @type {ol.TransformFunction|undefined} */ - this.transform_ = ol.Projection.identityTransform; + this.transform_ = undefined; /** * @private - * @type {Array.} + * @type {ol.Projection} */ - this.mapListenerKeys_ = null; + this.transformProjection_ = null; /** * @private - * @type {Array.} + * @type {Array.} */ - this.viewListenerKeys_ = null; + this.listenerKeys_ = null; - this.handleViewProjectionChanged_(); }; goog.inherits(ol.control.MousePosition, ol.control.Control); /** - * @private + * @param {ol.MapEvent} mapEvent Map event. + * @protected */ -ol.control.MousePosition.prototype.handleMapViewChanged_ = function() { - var map = this.getMap(); - goog.asserts.assert(!goog.isNull(map)); - if (!goog.isNull(this.viewListenerKeys_)) { - goog.array.forEach(this.viewListenerKeys_, goog.events.unlistenByKey); - this.viewListenerKeys_ = null; - } - var view = map.getView(); - if (goog.isDefAndNotNull(view)) { - // FIXME works for View2D only - goog.asserts.assert(view instanceof ol.View2D); - this.viewListenerKeys_ = [ - goog.events.listen( - view, ol.Object.getChangedEventType(ol.View2DProperty.ROTATION), - this.handleViewProjectionChanged_, false, this) - ]; - this.handleViewProjectionChanged_(); +ol.control.MousePosition.prototype.handleMapPostrender = function(mapEvent) { + var frameState = mapEvent.frameState; + if (goog.isNull(frameState)) { + this.transform_ = undefined; + this.transformProjection_ = null; + } else { + var projection = frameState.view2DState.projection; + if (projection != this.transformProjection_) { + if (goog.isDef(this.projection_)) { + this.transform_ = ol.Projection.getTransform( + projection, this.projection_); + } else { + this.transform_ = ol.Projection.identityTransform; + } + this.transformProjection_ = projection; + } } }; @@ -103,21 +103,21 @@ ol.control.MousePosition.prototype.handleMapViewChanged_ = function() { * @protected */ ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) { - var map = this.getMap(); - var eventPosition = goog.style.getRelativePosition( - browserEvent, map.getViewport()); - var pixel = new ol.Pixel(eventPosition.x, eventPosition.y); - var coordinate = map.getCoordinateFromPixel(pixel); - var html; - if (!goog.isNull(coordinate)) { - coordinate = this.transform_(coordinate); - if (goog.isDef(this.coordinateFormat_)) { - html = this.coordinateFormat_(coordinate); - } else { - html = coordinate.toString(); + var html = this.undefinedHTML_; + if (goog.isDef(this.transform_)) { + var map = this.getMap(); + var eventPosition = goog.style.getRelativePosition( + browserEvent, map.getViewport()); + var pixel = new ol.Pixel(eventPosition.x, eventPosition.y); + var coordinate = map.getCoordinateFromPixel(pixel); + if (!goog.isNull(coordinate)) { + coordinate = this.transform_(coordinate); + if (goog.isDef(this.coordinateFormat_)) { + html = this.coordinateFormat_(coordinate); + } else { + html = coordinate.toString(); + } } - } else { - html = this.undefinedHtml_; } this.element.innerHTML = html; }; @@ -128,18 +128,7 @@ ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) { * @protected */ ol.control.MousePosition.prototype.handleMouseOut = function(browserEvent) { - this.element.innerHTML = this.undefinedHtml_; -}; - - -/** - * @private - */ -ol.control.MousePosition.prototype.handleViewProjectionChanged_ = function() { - this.updateTransform_(); - // FIXME should we instead re-calculate using the last known - // mouse position? - this.element.innerHTML = this.undefinedHtml_; + this.element.innerHTML = this.undefinedHTML_; }; @@ -147,44 +136,20 @@ ol.control.MousePosition.prototype.handleViewProjectionChanged_ = function() { * @inheritDoc */ ol.control.MousePosition.prototype.setMap = function(map) { - if (!goog.isNull(this.mapListenerKeys_)) { - goog.array.forEach(this.mapListenerKeys_, goog.events.unlistenByKey); - this.mapListenerKeys_ = null; + if (!goog.isNull(this.listenerKeys_)) { + goog.array.forEach(this.listenerKeys_, goog.events.unlistenByKey); + this.listenerKeys_ = null; } goog.base(this, 'setMap', map); if (!goog.isNull(map)) { var viewport = map.getViewport(); - this.listenerKeys = [ + this.listenerKeys_ = [ goog.events.listen(viewport, goog.events.EventType.MOUSEMOVE, this.handleMouseMove, false, this), goog.events.listen(viewport, goog.events.EventType.MOUSEOUT, this.handleMouseOut, false, this), - goog.events.listen(map, - ol.Object.getChangedEventType(ol.MapProperty.VIEW), - this.handleMapViewChanged_, false, this) + goog.events.listen(map, ol.MapEventType.POSTRENDER, + this.handleMapPostrender, false, this) ]; - this.updateTransform_(); - } -}; - - -/** - * @private - */ -ol.control.MousePosition.prototype.updateTransform_ = function() { - var map, view; - if (!goog.isNull(map = this.getMap()) && - !goog.isNull(view = map.getView())) { - // FIXME works for View2D only - goog.asserts.assert(view instanceof ol.View2D); - var viewProjection = view.getProjection(); - if (!goog.isDef(viewProjection) || !goog.isDef(this.projection_)) { - this.transform_ = ol.Projection.identityTransform; - } else { - this.transform_ = - ol.Projection.getTransform(viewProjection, this.projection_); - } - } else { - this.transform_ = ol.Projection.identityTransform; } }; From 06628a88e61cb38cd1a691d4c69e9458898ccc66 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Wed, 16 Jan 2013 10:20:00 +0100 Subject: [PATCH 2/2] Update mouse position on each frame --- src/ol/control/mousepositioncontrol.js | 99 +++++++++++++++++--------- 1 file changed, 66 insertions(+), 33 deletions(-) diff --git a/src/ol/control/mousepositioncontrol.js b/src/ol/control/mousepositioncontrol.js index 1d2fff1669..ec45c3cabf 100644 --- a/src/ol/control/mousepositioncontrol.js +++ b/src/ol/control/mousepositioncontrol.js @@ -54,15 +54,33 @@ ol.control.MousePosition = function(mousePositionOptions) { /** * @private - * @type {ol.TransformFunction|undefined} + * @type {string} */ - this.transform_ = undefined; + this.renderedHTML_ = element.innerHTML; /** * @private * @type {ol.Projection} */ - this.transformProjection_ = null; + this.mapProjection_ = null; + + /** + * @private + * @type {ol.TransformFunction} + */ + this.transform_ = ol.Projection.identityTransform; + + /** + * @private + * @type {ol.Projection} + */ + this.renderedProjection_ = null; + + /** + * @private + * @type {ol.Pixel} + */ + this.lastMouseMovePixel_ = null; /** * @private @@ -81,20 +99,11 @@ goog.inherits(ol.control.MousePosition, ol.control.Control); ol.control.MousePosition.prototype.handleMapPostrender = function(mapEvent) { var frameState = mapEvent.frameState; if (goog.isNull(frameState)) { - this.transform_ = undefined; - this.transformProjection_ = null; + this.mapProjection_ = null; } else { - var projection = frameState.view2DState.projection; - if (projection != this.transformProjection_) { - if (goog.isDef(this.projection_)) { - this.transform_ = ol.Projection.getTransform( - projection, this.projection_); - } else { - this.transform_ = ol.Projection.identityTransform; - } - this.transformProjection_ = projection; - } + this.mapProjection_ = frameState.view2DState.projection; } + this.updateHTML_(this.lastMouseMovePixel_); }; @@ -103,23 +112,12 @@ ol.control.MousePosition.prototype.handleMapPostrender = function(mapEvent) { * @protected */ ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) { - var html = this.undefinedHTML_; - if (goog.isDef(this.transform_)) { - var map = this.getMap(); - var eventPosition = goog.style.getRelativePosition( - browserEvent, map.getViewport()); - var pixel = new ol.Pixel(eventPosition.x, eventPosition.y); - var coordinate = map.getCoordinateFromPixel(pixel); - if (!goog.isNull(coordinate)) { - coordinate = this.transform_(coordinate); - if (goog.isDef(this.coordinateFormat_)) { - html = this.coordinateFormat_(coordinate); - } else { - html = coordinate.toString(); - } - } - } - this.element.innerHTML = html; + var map = this.getMap(); + var eventPosition = goog.style.getRelativePosition( + browserEvent, map.getViewport()); + var pixel = new ol.Pixel(eventPosition.x, eventPosition.y); + this.updateHTML_(pixel); + this.lastMouseMovePixel_ = pixel; }; @@ -128,7 +126,8 @@ ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) { * @protected */ ol.control.MousePosition.prototype.handleMouseOut = function(browserEvent) { - this.element.innerHTML = this.undefinedHTML_; + this.updateHTML_(null); + this.lastMouseMovePixel_ = null; }; @@ -153,3 +152,37 @@ ol.control.MousePosition.prototype.setMap = function(map) { ]; } }; + + +/** + * @param {?ol.Pixel} pixel Pixel. + * @private + */ +ol.control.MousePosition.prototype.updateHTML_ = function(pixel) { + var html = this.undefinedHTML_; + if (!goog.isNull(pixel)) { + if (this.renderedProjection_ != this.mapProjection_) { + if (goog.isDef(this.projection_)) { + this.transform_ = ol.Projection.getTransform( + this.mapProjection_, this.projection_); + } else { + this.transform_ = ol.Projection.identityTransform; + } + this.renderedProjection_ = this.mapProjection_; + } + var map = this.getMap(); + var coordinate = map.getCoordinateFromPixel(pixel); + if (!goog.isNull(coordinate)) { + coordinate = this.transform_(coordinate); + if (goog.isDef(this.coordinateFormat_)) { + html = this.coordinateFormat_(coordinate); + } else { + html = coordinate.toString(); + } + } + } + if (!goog.isDef(this.renderedHTML_) || html != this.renderedHTML_) { + this.element.innerHTML = html; + this.renderedHTML_ = html; + } +};