一、什么是Popup弹窗

当点击某个元素时,显示一个弹窗,在弹窗中显示详细信息。

二、为什么需要pop弹窗

当详细信息很多时,不可能一次性全部

三、如何实现

pop弹窗在技术上主要是借助overlay遮罩

3-1、开发流程

  1. 1、创建一个DOM元素,并设置样式
  2. 2、将DOM转换成overlay
  3. 3、监听点击事件,判断如果点击的区域内存在点要素,就显示overlay

3-2、涉及的类

  1. // 二. 将dom转换成overlay
  2. const popup = new ol.Overlay({
  3. //要转换成overlay的HTML元素
  4. element: document.querySelector('#popup'),
  5. //当前窗口可见
  6. autoPan: true,
  7. //Popup放置的位置
  8. positioning: 'bottom-center',
  9. //是否应该停止事件传播到地图窗口
  10. stopEvent: true,
  11. autoPanAnimation: {
  12. //当Popup超出地图边界时,为了Popup全部可见,地图移动的速度
  13. duration: 250,
  14. }
  15. })

四、案例

4-1、创建DOM

  1. <div id="mapCon">
  2. <!-- Popup -->
  3. <div id="popup" class="ol-popup">
  4. <a href="#" id="popup-closer" class="ol-popup-closer"></a>
  5. <div id="popup-content">
  6. <h2>武汉</h2>
  7. <img src="../image/location.png" />
  8. </div>
  9. </div>
  10. </div>

样式部分

  1. .ol-popup {
  2. position: absolute;
  3. background-color: white;
  4. -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  5. filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  6. padding: 15px;
  7. border-radius: 10px;
  8. border: 1px solid #cccccc;
  9. bottom: 45px;
  10. left: -50px;
  11. z-index: 999;
  12. }
  13. .ol-popup:after,
  14. .ol-popup:before {
  15. top: 100%;
  16. border: solid transparent;
  17. content: ' ';
  18. height: 0;
  19. width: 0;
  20. position: absolute;
  21. pointer-events: none;
  22. }
  23. .ol-popup:after {
  24. border-top-color: white;
  25. border-width: 10px;
  26. left: 48px;
  27. margin-left: -10px;
  28. }
  29. .ol-popup:before {
  30. border-top-color: #cccccc;
  31. border-width: 11px;
  32. left: 48px;
  33. margin-left: -11px;
  34. }
  35. .ol-popup-closer {
  36. text-decoration: none;
  37. position: absolute;
  38. top: 2px;
  39. right: 8px;
  40. }
  41. .ol-popup-closer:after {
  42. content: '✖';
  43. }
  44. #popup-content {
  45. font-size: 14px;
  46. font-family: '微软雅黑';
  47. }
  48. #popup-content img {
  49. width: 30px;
  50. }

4-2、创建Overlay层

overlay是地图上的一个透明层

  1. // 二. 将dom转换成overlay
  2. var container = document.getElementById('popup');
  3. var content = document.getElementById('popup-content');
  4. var closer = document.getElementById('popup-closer')
  5. const popup = new ol.Overlay({
  6. //要转换成overlay的HTML元素
  7. element:container
  8. //当前窗口可见
  9. autoPan: true,
  10. //Popup放置的位置
  11. positioning: 'bottom-center',
  12. //是否应该停止事件传播到地图窗口
  13. stopEvent: true,
  14. autoPanAnimation: {
  15. //当Popup超出地图边界时,为了Popup全部可见,地图移动的速度
  16. duration: 250,
  17. },
  18. })
  19. map.addOverlay(popup)

4-3、监听点击事件

  1. //添加关闭按钮的单击事件(隐藏popup)
  2. closer.onclick = function () {
  3. //未定义popup位置
  4. popup.setPosition(undefined);
  5. //失去焦点
  6. closer.blur();
  7. return false;
  8. };
  9. // 为map添加点击事件监听,渲染弹出popup
  10. map.on('click', function (e) {
  11. // 获取当前点击的点是否存在要素, 并返回
  12. const feature = map.forEachFeatureAtPixel(
  13. //
  14. e.pixel,
  15. function (feature, layer) {
  16. return feature
  17. }
  18. )
  19. if (feature) {
  20. if (popup.getPosition() == undefined) {
  21. var position = feature.getGeometry().flatCoordinates
  22. popup.setPosition(position)
  23. }
  24. }
  25. })
  26. //为map添加鼠标移动事件监听,当指向标注时改变鼠标光标状态
  27. map.on('pointermove', function (e) {
  28. var pixel = map.getEventPixel(e.originalEvent);
  29. var hit = map.hasFeatureAtPixel(pixel);
  30. map.getTargetElement().style.cursor = hit ? 'pointer' : '';
  31. });

五、完整示例

  1. <body>
  2. <div id="map_container">
  3. <div id="popup" class="ol-popup">
  4. <a href="#" id="popup-closer" class="ol-popup-closer"></a>
  5. <div id="popup-content">
  6. <h2>武汉</h2>
  7. <img src="./image/location.png" alt="">
  8. </div>
  9. </div>
  10. </div>
  11. <script>
  12. var map = new ol.Map({
  13. target: "map_container",
  14. layers: [gaodeMapLayer],
  15. view: new ol.View({
  16. projection: 'EPSG:4326',
  17. center: [114.30, 30.50],
  18. zoom: 4
  19. })
  20. })
  21. var labelStyle = new ol.style.Style({
  22. image: new ol.style.Icon(
  23. /** @type {olx.style.IconOptions} */
  24. ({
  25. anchor: [0.5, 60],
  26. anchorOrigin: 'top-right',
  27. anchorXUnits: 'fraction',
  28. anchorYUnits: 'pixels',
  29. offsetOrigin: 'top-right',
  30. // offset:[0,10],
  31. //图标缩放比例
  32. // scale:0.5,
  33. //透明度
  34. opacity: 0.75,
  35. //图标的url
  36. src: './image/location.png'
  37. })),
  38. text: new ol.style.Text({
  39. //位置
  40. textAlign: 'center',
  41. //基准线
  42. textBaseline: 'middle',
  43. //文字样式
  44. font: 'normal 14px 微软雅黑',
  45. //文本内容
  46. text: "武汉市",
  47. //文本填充样式(即文字颜色)
  48. fill: new ol.style.Fill({
  49. color: '#aa3300'
  50. }),
  51. stroke: new ol.style.Stroke({
  52. color: '#ffcc33',
  53. width: 2
  54. })
  55. })
  56. });
  57. var Point = new ol.Feature({
  58. geometry: new ol.geom.Point([114.30, 30.50])
  59. })
  60. Point.setStyle(labelStyle)
  61. var source = new ol.source.Vector({
  62. features: [Point]
  63. })
  64. var layer = new ol.layer.Vector({
  65. source
  66. })
  67. map.addLayer(layer);
  68. /**
  69. * 实现popup的html元素
  70. */
  71. var container = document.getElementById('popup');
  72. var content = document.getElementById('popup-content');
  73. var closer = document.getElementById('popup-closer');
  74. /**
  75. * 1、在地图容器中创建一个Overlay
  76. */
  77. var popup = new ol.Overlay(
  78. /** @type {olx.OverlayOptions} */
  79. ({
  80. //要转换成overlay的HTML元素
  81. element: container,
  82. //当前窗口可见
  83. autoPan: true,
  84. //Popup放置的位置
  85. positioning: 'bottom-center',
  86. //是否应该停止事件传播到地图窗口
  87. stopEvent: false,
  88. autoPanAnimation: {
  89. //当Popup超出地图边界时,为了Popup全部可见,地图移动的速度
  90. duration: 250
  91. }
  92. }));
  93. map.addOverlay(popup);
  94. /**
  95. * 2、添加关闭按钮的单击事件(隐藏popup)
  96. * @return {boolean} Don't follow the href.
  97. */
  98. closer.onclick = function () {
  99. //未定义popup位置
  100. popup.setPosition(undefined);
  101. //失去焦点
  102. closer.blur();
  103. return false;
  104. };
  105. /**
  106. * 3、为map添加点击事件监听,渲染弹出popup
  107. */
  108. map.on('click', function (evt) {
  109. //判断当前单击处是否有要素,捕获到要素时弹出popup
  110. var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
  111. return feature;
  112. });
  113. if (feature) {
  114. var position = feature.getGeometry().flatCoordinates
  115. if (popup.getPosition() == undefined) {
  116. //设置popup的位置
  117. popup.setPosition(position);
  118. }
  119. }
  120. });
  121. /**
  122. * 为map添加鼠标移动事件监听,当指向标注时改变鼠标光标状态
  123. */
  124. map.on('pointermove', function (e) {
  125. var pixel = map.getEventPixel(e.originalEvent);
  126. var hit = map.hasFeatureAtPixel(pixel);
  127. map.getTargetElement().style.cursor = hit ? 'pointer' : '';
  128. });
  129. </script>
  130. </body>

:::tips 1、点击要素,出现一个popup弹窗,仅仅只针对openlayer的点要素
2、通过IG Server加载过来的点要素,仅仅是一张图片,在map容器上显示的不是一个要素。 :::