关于openlayers 弹窗 Overly 显示和隐藏控制的问题(踩坑记录)

579 阅读1分钟

最近在学习openlayers的过程中,学习了肉质星座的一篇教程vue+OpenLayers项目实践(一):基本绘制与点击弹窗 - 掘金 (juejin.cn)。 但是在过程中发现了一个问题,当使用v-if或v-show来控制popup弹窗的显示和隐藏时会出现地图自己移动的问题。

大概原因猜测可能是操作dom元素时导致页面回流和重绘,map组件重新获取了自己的size,导致popup弹窗出现时,即使坐标点在map中央也会导致地图触发autoPan,从而触发地图的移动。
所以这里建议使用 popup.setPosition() 来控制弹窗的位置和显示隐藏。
popup.setPosition() 本来是作为给弹窗设置经纬度的方法,但是在 popup.setPosition(undefined) 的情况下,会将popup弹窗隐藏。

水平有限以上表述不一定正确

  <div class="map-page">
    <div id="map" class="map_c"></div>
    <div ref="popupRef" class="popup">
      <div class="info">
        <ul>
          <li>信息1:xxx</li>
          <li>信息2:xxx</li>
          <li>信息3:xxx</li>
        </ul>
      </div>
    </div>
  </div>
</template>


<script setup>
import { ref, onMounted } from "vue";
import { Map, View, Feature, Overlay } from "ol";
import "ol/ol.css";

const popupRef = ref(null);

const map = ref();
// 初始化map
const initMap = () => {
  map.value = new Map({XXXXX});
  let popup = new Overlay({
    element: popupRef.value,
    stopEvent: false,
    autoPan: true,
    autoPanAnimation: {
      duration: 250,
    },
    positioning: "bottom-center",
    offset: [0, -30],
  });
  // 将定义好的popup加入map
  map.value.addOverlay(popup);
  map.value.on("singleclick", (e) => {
    let feature = map.value.forEachFeatureAtPixel(e.pixel, (feature) => feature);
    if (feature) {
      // 获取坐标位置
      let coordinates = feature.getGeometry().getCoordinates();
      // 设置弹窗位置
      popup.setPosition(coordinates);
    } else {
      // 弹窗位置为undefined 则隐藏
      popup.setPosition(undefined);
    }
  });
};

onMounted(() => {
  initMap();
});
</script>
<style lang="scss" scoped>
.map-page {
  .map_c {
    width: 800px;
    height: 600px;
    border: 1px solid #eee;
  }
}
.popup {
  width: 200px;
  background-color: white;
  padding: 18px;
  border-radius: 10px;
  box-shadow: 0 0 15px rgb(177, 177, 177);
  .info {
    color: #000;
    font-size: 14px;
    text-align: left;
    ul {
      padding-left: 0;
    }
  }
}
</style>