adds autosizing and image loading listener

This commit is contained in:
Mike Adair
2012-06-22 10:52:58 -04:00
parent 675dd2b47e
commit 2163d54323
2 changed files with 66 additions and 12 deletions
+2 -4
View File
@@ -386,21 +386,19 @@ ol.Map.prototype.moveByPx = function(dx, dy) {
}; };
/** /**
* @param {ol.Loc} loc the location being requested * @param {ol.geom.Point} loc the location being requested
* @returns {Object} the * @returns {Object} the
*/ */
ol.Map.prototype.getViewportPosition = function(loc) { ol.Map.prototype.getViewportPosition = function(loc) {
//TODO: delegate this to the renderers //TODO: delegate this to the renderers
//stub for now to get popups working //stub for now to get popups working
return {x: 200, y: 300}; return [200, 300];
}; };
/** /**
* @returns {Element} the map overlay element * @returns {Element} the map overlay element
*/ */
ol.Map.prototype.getMapOverlay = function() { ol.Map.prototype.getMapOverlay = function() {
//TODO: delegate this to the renderers
//stub for now to get popups working
return this.mapOverlay_ return this.mapOverlay_
}; };
+64 -8
View File
@@ -66,7 +66,15 @@ ol.Popup = function(map, opt_anchor, opt_placement, opt_close) {
* @private * @private
* @type {number} * @type {number}
*/ */
this.arrowOffset_ = 32; //FIXME: set this from CSS dynamically somehow? this.arrowOffset_ = 30; //FIXME: set this from CSS dynamically somehow?
/**
* if the CSS sets either width or height assume the app is specifying the
* size of the popup, if not auto size the popup.
* @private
* @type {boolean}
*/
this.autoSize_ = true;
}; };
@@ -190,6 +198,12 @@ ol.Popup.prototype.open = function(opt_arg) {
goog.dom.classes.add(this.container_, goog.dom.classes.add(this.container_,
ol.Popup.CLASS_NAME, ol.Popup.CLASS_NAME+'-'+this.placement_); ol.Popup.CLASS_NAME, ol.Popup.CLASS_NAME+'-'+this.placement_);
//see if the style class sets width or height
if (goog.style.getStyle(this.container_, 'width').length>0 ||
goog.style.getStyle(this.container_, 'height').length>0 ) {
this.autoSize_ = false;
}
if (this.closeButton_) { if (this.closeButton_) {
var closeButton = goog.dom.createElement('div'); var closeButton = goog.dom.createElement('div');
goog.dom.appendChild(this.container_, closeButton); goog.dom.appendChild(this.container_, closeButton);
@@ -202,12 +216,28 @@ ol.Popup.prototype.open = function(opt_arg) {
this.childContent_=goog.dom.htmlToDocumentFragment(this.generateContent_()); this.childContent_=goog.dom.htmlToDocumentFragment(this.generateContent_());
goog.dom.appendChild(this.container_, this.childContent_); goog.dom.appendChild(this.container_, this.childContent_);
if (this.autoSize_) {
this.registerImageListeners();
}
this.setAnchorOffset_();
};
ol.Popup.prototype.setAnchorOffset_ = function() {
if (goog.isNull(this.container_.parentNode)) {
//this means the popup has already been closed, nothing to do here
//which might happen while waiting for images to load
return;
}
//position the element //position the element
if (this.anchor_ instanceof ol.Feature) { if (this.anchor_ instanceof ol.Feature) {
this.pos_ = this.anchor_.getGeometry().getCentroid(); this.pos_ = this.anchor_.getGeometry().getCentroid();
} else { } else {
this.pos_ = this.anchor_; this.pos_ = this.anchor_;
} }
var popupPosPx = this.map_.getViewportPosition(this.pos_); var popupPosPx = this.map_.getViewportPosition(this.pos_);
var popupSize = goog.style.getSize(this.container_); var popupSize = goog.style.getSize(this.container_);
@@ -218,22 +248,22 @@ ol.Popup.prototype.open = function(opt_arg) {
break; break;
case 'top': case 'top':
case 'bottom': case 'bottom':
popupPosPx.x -= popupSize.width / 2.0; popupPosPx[0] -= popupSize.width / 2.0;
if (this.placement_ == "bottom") { if (this.placement_ == "bottom") {
popupPosPx.y -= popupSize.height + this.arrowOffset_; popupPosPx[1] -= popupSize.height + this.arrowOffset_;
} else { } else {
popupPosPx.y += this.arrowOffset_; popupPosPx[1] += this.arrowOffset_;
} }
break; break;
case 'left': case 'left':
case 'right': case 'right':
popupPosPx.y -= popupSize.height / 2.0; popupPosPx[1] -= popupSize.height / 2.0;
if (this.placement_ == "right") { if (this.placement_ == "right") {
popupPosPx.x -= popupSize.width + this.arrowOffset_; popupPosPx[0] -= popupSize.width + this.arrowOffset_;
} else { } else {
popupPosPx.x += this.arrowOffset_; popupPosPx[0] += this.arrowOffset_;
} }
break; break;
}; };
@@ -241,12 +271,38 @@ ol.Popup.prototype.open = function(opt_arg) {
}; };
/**
* registerImageListeners
* Called when an image contained by the popup loaded. this function
* updates the popup size, then unregisters the image load listener.
*/
ol.Popup.prototype.registerImageListeners = function() {
// As the images load, this function will call setAnchorOffset_() to
// resize the popup to fit the content div (which presumably is now
// bigger than when the image was not loaded).
//
//cycle through the images and if their size is 0x0, that means that
// they haven't been loaded yet, so we attach the listener, which
// will fire when the images finish loading and will resize the
// popup accordingly to its new size.
var images = this.container_.getElementsByTagName("img");
for (var i = 0, len = images.length; i < len; i++) {
var img = images[i];
if (img.width == 0 || img.height == 0) {
goog.events.listenOnce(img, 'load',
goog.bind(this.setAnchorOffset_, this));
}
}
};
/** /**
* @param px - {goog.} the top and left position of the popup div. * @param px - {goog.} the top and left position of the popup div.
*/ */
ol.Popup.prototype.moveTo_ = function(px) { ol.Popup.prototype.moveTo_ = function(px) {
if (goog.isDefAndNotNull(px)) { if (goog.isDefAndNotNull(px)) {
goog.style.setPosition(this.container_, px.x, px.y); goog.style.setPosition(this.container_, px[0], px[1]);
} }
}; };