返回

追随鼠标的点位详情弹窗——Cesium3+Vue3实现方案

前端

Cesium3+Vue3:构建动态交互式的点位详情弹窗

前言

地理信息系统(GIS)应用程序中,交互式点位详情弹窗至关重要,可帮助用户快速获取特定地物的信息。传统的弹窗通常固定位置,随着点位密集度的增加,操作不便。本文将介绍如何利用Cesium3和Vue3构建一个跟随鼠标的动态点位详情弹窗,提升GIS应用的交互体验。

技术栈

  • Cesium3:强大的3D地球可视化库
  • Vue3:高效的数据绑定和组件化前端框架

实现步骤

1. 初始化Cesium3和Vue3

import Cesium from "cesium";
import Vue from "vue";

Vue.component("cesium-viewer", {
  template: `<div id="cesium-viewer"></div>`,
  mounted() {
    this.viewer = new Cesium.Viewer("cesium-viewer");
  },
  beforeDestroy() {
    this.viewer.destroy();
  },
});

const app = new Vue({
  el: "#app",
  data: {
    pointFeatures: [],
  },
});

2. 创建点位要素

const pointFeatures = [
  {
    id: "feature1",
    position: Cesium.Cartesian3.fromDegrees(-122.4194, 37.7749),
    properties: {
      name: "San Francisco",
      population: 860000,
    },
  },
  {
    id: "feature2",
    position: Cesium.Cartesian3.fromDegrees(-118.2437, 34.0522),
    properties: {
      name: "Los Angeles",
      population: 3900000,
    },
  },
];

3. 将点位要素添加到场景中

for (let i = 0; i < pointFeatures.length; i++) {
  const feature = pointFeatures[i];
  const entity = this.viewer.entities.add({
    id: feature.id,
    position: feature.position,
    point: {
      pixelSize: 10,
      color: Cesium.Color.RED,
    },
    label: {
      text: feature.properties.name,
      font: "14px Arial",
      color: Cesium.Color.WHITE,
      showBackground: true,
      backgroundColor: Cesium.Color.BLACK,
    },
  });
}

4. 创建动态弹窗

const tooltip = document.createElement("div");
tooltip.classList.add("tooltip");
tooltip.style.position = "absolute";
tooltip.style.left = "0px";
tooltip.style.top = "0px";
tooltip.style.padding = "10px";
tooltip.style.backgroundColor = "white";
tooltip.style.border = "1px solid black";
document.body.appendChild(tooltip);

this.viewer.scene.postRender.addEventListener(() => {
  const pickedFeature = this.viewer.scene.pick(Cesium.Mouse.getPosition());
  if (pickedFeature && pickedFeature.id) {
    const pointFeature = pointFeatures.find(f => f.id === pickedFeature.id);
    if (pointFeature) {
      tooltip.style.display = "block";
      tooltip.style.left = Cesium.Mouse.getPosition().x + 10 + "px";
      tooltip.style.top = Cesium.Mouse.getPosition().y + 10 + "px";
      tooltip.innerHTML = `
        <p><strong>Name:</strong> ${pointFeature.properties.name}</p>
        <p><strong>Population:</strong> ${pointFeature.properties.population}</p>
      `;
    } else {
      tooltip.style.display = "none";
    }
  } else {
    tooltip.style.display = "none";
  }
});

优势

  • 动态跟随鼠标,交互性强
  • Vue3组件封装,易于集成和维护
  • 可定制化样式,满足不同应用需求

扩展使用

  • 响应式弹窗: 根据屏幕尺寸调整弹窗大小和位置,提升用户体验。
  • 鼠标事件: 添加鼠标悬停、点击等事件处理,提供更多交互选项。
  • 数据绑定: 利用Vue3的数据绑定,实时更新弹窗内容,保持信息同步。

优化方法

  • 性能优化: 使用requestAnimationFrame和延迟更新等技术,提高弹窗响应速度。
  • 缓存数据: 预先加载和缓存点位数据,减少弹窗加载时间。
  • 代码分块: 将弹窗相关的代码分离成独立模块,便于维护和扩展。

常见问题解答

Q:如何更改弹窗样式?
A:可以通过CSS样式修改tooltip元素的属性,如background-colorborderfont-size等。

Q:如何获取点位的更多信息?
A:可以通过Cesium3的pickedFeature.getProperty方法获取点位的自定义属性值。

Q:如何让弹窗固定在点位上方?
A:在弹窗样式中设置position: fixed;,并通过计算点位屏幕坐标确定弹窗的位置。

Q:如何限制弹窗在特定区域内显示?
A:可以使用CSS样式的max-widthmax-height属性限制弹窗的尺寸,并在弹窗样式中添加overflow: scroll;允许内容滚动。

Q:如何提高弹窗的可用性?
A:遵循可访问性指南,如提供替代文本、使用高对比度颜色,确保弹窗在不同设备和环境下都能被访问。