Anchored.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the 2-clause BSD license.
  3. * See license.txt in the OpenLayers distribution or repository for the
  4. * full text of the license. */
  5. /**
  6. * @requires OpenLayers/Popup.js
  7. */
  8. /**
  9. * Class: OpenLayers.Popup.Anchored
  10. *
  11. * Inherits from:
  12. * - <OpenLayers.Popup>
  13. */
  14. OpenLayers.Popup.Anchored =
  15. OpenLayers.Class(OpenLayers.Popup, {
  16. /**
  17. * Property: relativePosition
  18. * {String} Relative position of the popup ("br", "tr", "tl" or "bl").
  19. */
  20. relativePosition: null,
  21. /**
  22. * APIProperty: keepInMap
  23. * {Boolean} If panMapIfOutOfView is false, and this property is true,
  24. * contrain the popup such that it always fits in the available map
  25. * space. By default, this is set. If you are creating popups that are
  26. * near map edges and not allowing pannning, and especially if you have
  27. * a popup which has a fixedRelativePosition, setting this to false may
  28. * be a smart thing to do.
  29. *
  30. * For anchored popups, default is true, since subclasses will
  31. * usually want this functionality.
  32. */
  33. keepInMap: true,
  34. /**
  35. * Property: anchor
  36. * {Object} Object to which we'll anchor the popup. Must expose a
  37. * 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>).
  38. */
  39. anchor: null,
  40. /**
  41. * Constructor: OpenLayers.Popup.Anchored
  42. *
  43. * Parameters:
  44. * id - {String}
  45. * lonlat - {<OpenLayers.LonLat>}
  46. * contentSize - {<OpenLayers.Size>}
  47. * contentHTML - {String}
  48. * anchor - {Object} Object which must expose a 'size' <OpenLayers.Size>
  49. * and 'offset' <OpenLayers.Pixel> (generally an <OpenLayers.Icon>).
  50. * closeBox - {Boolean}
  51. * closeBoxCallback - {Function} Function to be called on closeBox click.
  52. */
  53. initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox,
  54. closeBoxCallback) {
  55. var newArguments = [
  56. id, lonlat, contentSize, contentHTML, closeBox, closeBoxCallback
  57. ];
  58. OpenLayers.Popup.prototype.initialize.apply(this, newArguments);
  59. this.anchor = (anchor != null) ? anchor
  60. : { size: new OpenLayers.Size(0,0),
  61. offset: new OpenLayers.Pixel(0,0)};
  62. },
  63. /**
  64. * APIMethod: destroy
  65. */
  66. destroy: function() {
  67. this.anchor = null;
  68. this.relativePosition = null;
  69. OpenLayers.Popup.prototype.destroy.apply(this, arguments);
  70. },
  71. /**
  72. * APIMethod: show
  73. * Overridden from Popup since user might hide popup and then show() it
  74. * in a new location (meaning we might want to update the relative
  75. * position on the show)
  76. */
  77. show: function() {
  78. this.updatePosition();
  79. OpenLayers.Popup.prototype.show.apply(this, arguments);
  80. },
  81. /**
  82. * Method: moveTo
  83. * Since the popup is moving to a new px, it might need also to be moved
  84. * relative to where the marker is. We first calculate the new
  85. * relativePosition, and then we calculate the new px where we will
  86. * put the popup, based on the new relative position.
  87. *
  88. * If the relativePosition has changed, we must also call
  89. * updateRelativePosition() to make any visual changes to the popup
  90. * which are associated with putting it in a new relativePosition.
  91. *
  92. * Parameters:
  93. * px - {<OpenLayers.Pixel>}
  94. */
  95. moveTo: function(px) {
  96. var oldRelativePosition = this.relativePosition;
  97. this.relativePosition = this.calculateRelativePosition(px);
  98. OpenLayers.Popup.prototype.moveTo.call(this, this.calculateNewPx(px));
  99. //if this move has caused the popup to change its relative position,
  100. // we need to make the appropriate cosmetic changes.
  101. if (this.relativePosition != oldRelativePosition) {
  102. this.updateRelativePosition();
  103. }
  104. },
  105. /**
  106. * APIMethod: setSize
  107. *
  108. * Parameters:
  109. * contentSize - {<OpenLayers.Size>} the new size for the popup's
  110. * contents div (in pixels).
  111. */
  112. setSize:function(contentSize) {
  113. OpenLayers.Popup.prototype.setSize.apply(this, arguments);
  114. if ((this.lonlat) && (this.map)) {
  115. var px = this.map.getLayerPxFromLonLat(this.lonlat);
  116. this.moveTo(px);
  117. }
  118. },
  119. /**
  120. * Method: calculateRelativePosition
  121. *
  122. * Parameters:
  123. * px - {<OpenLayers.Pixel>}
  124. *
  125. * Returns:
  126. * {String} The relative position ("br" "tr" "tl" "bl") at which the popup
  127. * should be placed.
  128. */
  129. calculateRelativePosition:function(px) {
  130. var lonlat = this.map.getLonLatFromLayerPx(px);
  131. var extent = this.map.getExtent();
  132. var quadrant = extent.determineQuadrant(lonlat);
  133. return OpenLayers.Bounds.oppositeQuadrant(quadrant);
  134. },
  135. /**
  136. * Method: updateRelativePosition
  137. * The popup has been moved to a new relative location, so we may want to
  138. * make some cosmetic adjustments to it.
  139. *
  140. * Note that in the classic Anchored popup, there is nothing to do
  141. * here, since the popup looks exactly the same in all four positions.
  142. * Subclasses such as Framed, however, will want to do something
  143. * special here.
  144. */
  145. updateRelativePosition: function() {
  146. //to be overridden by subclasses
  147. },
  148. /**
  149. * Method: calculateNewPx
  150. *
  151. * Parameters:
  152. * px - {<OpenLayers.Pixel>}
  153. *
  154. * Returns:
  155. * {<OpenLayers.Pixel>} The the new px position of the popup on the screen
  156. * relative to the passed-in px.
  157. */
  158. calculateNewPx:function(px) {
  159. var newPx = px.offset(this.anchor.offset);
  160. //use contentSize if size is not already set
  161. var size = this.size || this.contentSize;
  162. var top = (this.relativePosition.charAt(0) == 't');
  163. newPx.y += (top) ? -size.h : this.anchor.size.h;
  164. var left = (this.relativePosition.charAt(1) == 'l');
  165. newPx.x += (left) ? -size.w : this.anchor.size.w;
  166. return newPx;
  167. },
  168. CLASS_NAME: "OpenLayers.Popup.Anchored"
  169. });