Merge pull request #30 from openlayers/overlay

Introducing ol.overlay.Overlay and an overlayContainer. r=@twpayne
This commit is contained in:
ahocevar
2012-09-28 04:05:21 -07:00
9 changed files with 225 additions and 22 deletions

View File

@@ -1,4 +1,4 @@
.ol-viewport {
.ol-viewport .ol-unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;

View File

@@ -5,6 +5,7 @@ goog.require('ol.Collection');
goog.require('ol.Coordinate');
goog.require('ol.Map');
goog.require('ol.MapOptions'); // FIXME this should not be required
goog.require('ol.overlay.Overlay');
goog.require('ol.source.MapQuestOpenAerial');
@@ -22,3 +23,9 @@ var map = new ol.Map(document.getElementById('map'), {
layers: new ol.Collection([layer]),
zoom: 2
});
var vienna = new ol.overlay.Overlay({
map: map,
coordinate: ol.Projection.transformWithCodes(
new ol.Coordinate(16, 48), 'EPSG:4326', 'EPSG:3857'),
element: document.getElementById('vienna')
});

View File

@@ -67,7 +67,8 @@ ol.control.Control.prototype.setMap = function(map) {
}
this.map_ = map;
if (!goog.isNull(this.map_)) {
var target = goog.isDef(this.target_) ? this.target_ : map.getViewport();
var target = goog.isDef(this.target_) ?
this.target_ : map.getOverlayContainer();
goog.dom.appendChild(target, this.element);
}
};

View File

@@ -42,10 +42,7 @@ ol.control.Zoom = function(zoomOptions) {
goog.events.listen(outElement, eventType, this.handleOut_, false, this);
var element = goog.dom.createDom(
goog.dom.TagName.DIV, 'ol-zoom', inElement, outElement);
goog.events.listen(
element, ol.BrowserFeature.HAS_TOUCH ? goog.events.EventType.TOUCHSTART :
goog.events.EventType.MOUSEDOWN, goog.events.Event.stopPropagation);
goog.dom.TagName.DIV, 'ol-zoom ol-unselectable', inElement, outElement);
goog.base(this, {
element: element,

View File

@@ -24,6 +24,7 @@ goog.require('goog.functions');
goog.require('goog.fx.anim');
goog.require('goog.fx.anim.Animated');
goog.require('goog.object');
goog.require('ol.BrowserFeature');
goog.require('ol.Collection');
goog.require('ol.Color');
goog.require('ol.Constraints');
@@ -63,14 +64,6 @@ ol.MapProperty = {
};
/**
* @enum {number}
*/
ol.MapPaneZIndex = {
VIEWPORT: 1000
};
/**
* @constructor
@@ -145,15 +138,25 @@ ol.Map = function(container, mapOptionsLiteral) {
* @private
* @type {Element}
*/
this.viewport_ = goog.dom.createElement(goog.dom.TagName.DIV);
this.viewport_.className = 'ol-viewport';
this.viewport_ = goog.dom.createDom(goog.dom.TagName.DIV, 'ol-viewport');
this.viewport_.style.position = 'relative';
this.viewport_.style.overflow = 'hidden';
this.viewport_.style.width = '100%';
this.viewport_.style.height = '100%';
this.viewport_.style.zIndex = ol.MapPaneZIndex.VIEWPORT;
goog.dom.appendChild(container, this.viewport_);
/**
* @private
* @type {Element}
*/
this.overlayContainer_ = goog.dom.createDom(goog.dom.TagName.DIV,
'ol-overlaycontainer');
goog.events.listen(this.overlayContainer_,
ol.BrowserFeature.HAS_TOUCH ?
goog.events.EventType.TOUCHSTART : goog.events.EventType.MOUSEDOWN,
goog.events.Event.stopPropagation);
goog.dom.appendChild(this.viewport_, this.overlayContainer_);
var mapBrowserEventHandler = new ol.MapBrowserEventHandler(this);
goog.events.listen(mapBrowserEventHandler, [
ol.MapBrowserEvent.EventType.CLICK,
@@ -504,6 +507,16 @@ ol.Map.prototype.getViewport = function() {
};
/**
* @return {Element} The map's overlay container. Elements added to this
* container won't let mousedown and touchstart events through to the map, so
* clicks and gestures on an overlay don't trigger any MapBrowserEvent.
*/
ol.Map.prototype.getOverlayContainer = function() {
return this.overlayContainer_;
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @param {string=} opt_type Type.

View File

@@ -170,7 +170,6 @@ ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) {
this.touchEnableBrowserEvent_(browserEvent);
var newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.CLICK, this.map_, browserEvent);
this.down_ = null;
this.dispatchEvent(newEvent);
}
};
@@ -181,7 +180,7 @@ ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) {
* @private
*/
ol.MapBrowserEventHandler.prototype.dblclick_ = function(browserEvent) {
if (!this.dragged_) {
if (!this.dragged_ && this.down_) {
var now = new Date().getTime();
if (!this.timestamp_ || now - this.timestamp_ > 250) {
this.timestamp_ = now;

185
src/ol/overlay/overlay.js Normal file
View File

@@ -0,0 +1,185 @@
goog.provide('ol.overlay.Overlay');
goog.provide('ol.overlay.OverlayOptions');
goog.provide('ol.overlay.OverlayPositioning');
goog.require('goog.events');
goog.require('goog.style');
goog.require('ol.Map');
goog.require('ol.MapProperty');
/**
* @typedef {{coordinate: (ol.Coordinate|undefined),
* element: (Element|undefined),
* map: (ol.Map|undefined),
* positioning: (Array.<string>|undefined)}}
*/
ol.overlay.OverlayOptions;
/**
* @constructor
* @param {ol.overlay.OverlayOptions} overlayOptions Overlay options.
*/
ol.overlay.Overlay = function(overlayOptions) {
/**
* @type {ol.Coordinate}
* @private
*/
this.coordinate_ = null;
/**
* @type {Element}
* @private
*/
this.element_ = null;
/**
* @private
* @type {ol.Map}
*/
this.map_ = null;
/**
* @type {Array.<string>}
* @private
*/
this.positioning_ = [
ol.overlay.OverlayPositioning.LEFT,
ol.overlay.OverlayPositioning.BOTTOM
];
/**
* @private
* @type {Array.<number>}
*/
this.mapListenerKeys_ = [];
if (goog.isDef(overlayOptions.coordinate)) {
this.setCoordinate(overlayOptions.coordinate);
}
if (goog.isDef(overlayOptions.element)) {
this.setElement(overlayOptions.element);
}
if (goog.isDef(overlayOptions.map)) {
this.setMap(overlayOptions.map);
}
if (goog.isDef(overlayOptions.positioning)) {
this.setPositioning(overlayOptions.positioning);
}
};
/**
* @param {ol.Coordinate} coordinate Coordinate for the overlay's position on
* the map.
*/
ol.overlay.Overlay.prototype.setCoordinate = function(coordinate) {
this.coordinate_ = coordinate;
this.updatePixelPosition_();
};
/**
* @param {Element} element The DOM element for the overlay.
*/
ol.overlay.Overlay.prototype.setElement = function(element) {
if (this.element_) {
goog.dom.removeNode(this.element_);
}
this.element_ = element;
if (this.map_) {
goog.dom.append(/** @type {!Node} */ (this.map_.getOverlayContainer()),
this.element_);
}
this.updatePixelPosition_();
};
/**
* @return {Element} The DOM element for the overlay.
*/
ol.overlay.Overlay.prototype.getElement = function() {
return this.element_;
};
/**
* @param {ol.Map} map Map.
*/
ol.overlay.Overlay.prototype.setMap = function(map) {
this.map_ = map;
goog.array.forEach(this.mapListenerKeys_, goog.events.unlistenByKey);
if (this.element_) {
this.setElement(this.element_);
}
this.mapListenerKeys_ = map ? [
goog.events.listen(
map, ol.Object.getChangedEventType(ol.MapProperty.CENTER),
this.updatePixelPosition_, false, this),
goog.events.listen(
map, ol.Object.getChangedEventType(ol.MapProperty.RESOLUTION),
this.updatePixelPosition_, false, this),
goog.events.listen(
map, ol.Object.getChangedEventType(ol.MapProperty.ROTATION),
this.updatePixelPosition_, false, this),
goog.events.listen(
map, ol.Object.getChangedEventType(ol.MapProperty.SIZE),
this.updatePixelPosition_, false, this)
] : [];
this.updatePixelPosition_();
};
/**
* @return {ol.Map} Map.
*/
ol.overlay.Overlay.prototype.getMap = function() {
return this.map_;
};
/**
* Set the CSS properties to use for x- and y-positioning of the element. If
* not set, the default is {@code ['left', 'bottom']}.
* @param {Array.<string>} positioning The positioning.
*/
ol.overlay.Overlay.prototype.setPositioning = function(positioning) {
this.positioning_ = positioning;
this.updatePixelPosition_();
};
/**
* @private
*/
ol.overlay.Overlay.prototype.updatePixelPosition_ = function() {
if (!goog.isNull(this.map_) && !goog.isNull(this.coordinate_) &&
!goog.isNull(this.element_)) {
var pixel = this.map_.getPixelFromCoordinate(this.coordinate_);
var mapSize = this.map_.get(ol.MapProperty.SIZE);
var x = Math.round(pixel.x);
if (this.positioning_[0] === ol.overlay.OverlayPositioning.RIGHT) {
x = mapSize.width - x;
}
var y = Math.round(pixel.y);
if (this.positioning_[1] === ol.overlay.OverlayPositioning.BOTTOM) {
y = mapSize.height - y;
}
goog.style.setStyle(this.element_, this.positioning_[0], x + 'px');
goog.style.setStyle(this.element_, this.positioning_[1], y + 'px');
}
};
/**
* @enum {string}
*/
ol.overlay.OverlayPositioning = {
LEFT: 'left',
RIGHT: 'right',
TOP: 'top',
BOTTOM: 'bottom'
};

View File

@@ -30,13 +30,13 @@ ol.renderer.dom.Map = function(container, map) {
* @private
*/
this.layersPane_ = goog.dom.createElement(goog.dom.TagName.DIV);
this.layersPane_.className = 'ol-layers-pane';
this.layersPane_.className = 'ol-layers-pane ol-unselectable';
var style = this.layersPane_.style;
style.position = 'absolute';
style.width = '100%';
style.height = '100%';
goog.dom.appendChild(container, this.layersPane_);
goog.dom.insertChildAt(container, this.layersPane_, 0);
/**
* @type {Object}

View File

@@ -151,7 +151,8 @@ ol.renderer.webgl.Map = function(container, map) {
this.canvas_ = goog.dom.createElement(goog.dom.TagName.CANVAS);
this.canvas_.height = container.clientHeight;
this.canvas_.width = container.clientWidth;
goog.dom.appendChild(container, this.canvas_);
this.canvas_.className = 'ol-unselectable';
goog.dom.insertChildAt(container, this.canvas_, 0);
/**
* @private