当前位置: 首页 > news >正文

Cesium快速入门到精通系列教程二十三:综合

一、viewer.cesiumWidget.container.appendChild()

把你自定义的 HTML 元素(弹窗、按钮、图标等)添加到 Cesium 画布的容器里,让它显示在 3D 地球场景上。

// 1. 创建一个自定义弹窗 div const infoDiv = document.createElement('div'); infoDiv.style.position = 'absolute'; infoDiv.style.top = '100px'; infoDiv.style.left = '100px'; infoDiv.style.background = 'white'; infoDiv.style.padding = '10px'; infoDiv.innerHTML = '我是显示在地球上的自定义弹窗!'; // 2. 关键:把 div 添加到 Cesium 根容器 viewer.cesiumWidget.container.appendChild(infoDiv);

如何删除?

方法 1:直接从父容器移除(最简单)

// 直接删除你创建的 infoDiv infoDiv.remove();

这行代码就能把弹窗从页面上彻底删掉。

方法 2:安全判断式删除(推荐)

防止元素已经被删了导致报错:

if (infoDiv && infoDiv.parentNode) { infoDiv.parentNode.removeChild(infoDiv); }

如果要多次开关弹窗

建议把弹窗存成全局变量,方便开关:

// 全局保存 window.infoDiv = infoDiv; // 删除 window.infoDiv?.remove();

二、viewer..entities.values作用

viewer.entities.values 是一个数组,里面包含了你在 Cesium 中添加的所有实体(点、线、面、标注、模型等),可以用来遍历、查询、修改、删除全部实体。

核心作用(最常用)

1、遍历所有实体(最常用)

批量修改、隐藏、删除所有实体:

// 遍历场景中所有实体 viewer.entities.values.forEach(entity => { // 示例1:隐藏所有实体 entity.show = false; // 示例2:修改所有点的颜色 if (entity.point) { entity.point.color = Cesium.Color.RED; } });

2、获取实体总数

const count = viewer.entities.values.length; console.log('场景中共有实体:', count);

3、清空所有实体(替代 removeAll())

// 清空所有实体 viewer.entities.removeAll(); // 等价于遍历删除(不推荐,仅理解用) viewer.entities.values.forEach(entity => { viewer.entities.remove(entity); });

4、查找符合条件的实体

// 查找所有名称为 "测试点" 的实体 const targetEntities = viewer.entities.values.filter(e => e.name === '测试点');

三、viewer.scene.canvas.height

viewer.scene.canvas.height 用来获取 / 设置 Cesium 3D 地球画布的高度(像素值),直接控制地球显示区域的高度大小。

  • viewer.scene.canvas

→ Cesium 真正渲染 3D 地球的画布元素(就是一个 <canvas> HTML 标签)

  • .height

→ 这个 canvas 元素的高度属性(单位:像素 px)

核心作用

① 获取当前地球画布的真实高度(只读常用)

// 获取当前 Cesium 画布高度(像素) const canvasHeight = viewer.scene.canvas.height; console.log('地球高度:', canvasHeight);

② 动态修改地球高度(很少直接用)

// 强制把地球高度改成 500px viewer.scene.canvas.height = 500;

正确获取显示高度:用 offsetHeight

如果你想知道页面上实际显示的地球高度,要用:

viewer.scene.canvas.offsetHeight // 真实显示高度(推荐)

因为:

canvas.height = 绘图分辨率高度(内部渲染尺寸)

canvas.offsetHeight = 页面显示高度(肉眼看到的尺寸)

两者不一定相等!

四、viewer.scene.cartesianToCanvasCoordinates()

这是 Cesium 中核心坐标转换 API,专门用来把3D 世界坐标(Cartesian3) 转换成浏览器 2D 屏幕坐标(Canvas 坐标),是实现自定义 DOM 弹窗、标签、跟随鼠标元素的关键方法。

一句话总结:

将 Cesium 三维场景中的点,转换成浏览器画布上的像素坐标(x, y)让你知道:3D 世界里的某个点,在屏幕上显示在哪个位置。

// 1. 定义一个3D世界坐标(比如北京) const position = Cesium.Cartesian3.fromDegrees(116.4, 39.9, 100); // 2. 创建你的自定义DOM弹窗 const infoDiv = document.createElement('div'); infoDiv.style.position = 'absolute'; infoDiv.style.background = 'white'; infoDiv.innerHTML = '我是绑定在3D点上的弹窗'; viewer.cesiumWidget.container.appendChild(infoDiv); // 3. 实时更新弹窗屏幕位置(关键!) viewer.scene.postRender.addEventListener(() => { // 核心:3D坐标 → 屏幕坐标 const canvasPosition = viewer.scene.cartesianToCanvasCoordinates(position); if (Cesium.defined(canvasPosition)) { // 把屏幕坐标赋值给DOM infoDiv.style.left = canvasPosition.x + 'px'; infoDiv.style.top = canvasPosition.y + 'px'; } });

输入:

Cartesian3 坐标:Cesium 3D 场景中的点(经纬度转的世界坐标、实体位置、模型位置等)

输出:

Cartesian2 坐标:包含 x、y 属性,单位是像素

x:距离浏览器画布左侧的像素距离

y:距离浏览器画布顶部的像素距离

关键特性 & 注意事项:

必须在渲染循环中调用地球转动、缩放时,屏幕坐标会实时变化,所以要放在 postRender 事件里更新。

坐标原点转换后的 x/y 是相对于 Cesium Canvas 画布,不是整个浏览器窗口。

五、viewer.scene.postRender.addEventListener()

在 Cesium 地球每完成一帧渲染之后 **,自动执行你指定的代码,用来做实时更新、动画、跟随、动态效果等。

1. 它到底是什么?

viewer.scene.postRender

→ 渲染完成事件(每一帧渲染完都会触发一次)

addEventListener()

→ 给这个事件绑定一个监听函数

简单理解:

Cesium 地球每秒会刷新 60 次(60 帧)

每刷新完一帧画面,就立刻执行一次你写的函数

相当于一个无限循环的实时更新器

2. 核心作用(最常用场景)

它专门用来做必须实时更新的功能:

让弹窗 / 标签 跟随 3D 点位移动(最常用!)

动态修改实体属性(位置、颜色、大小)

自定义动画效果

实时计算相机位置

实时更新 UI 数据

3. 最典型使用示例(点位跟随弹窗)

// 1. 创建一个自定义 HTML 弹窗 const div = document.createElement('div'); div.style.position = 'absolute'; div.style.color = 'white'; div.innerHTML = '我会跟着点位动'; viewer.cesiumWidget.container.appendChild(div); // 2. 重点:每帧渲染后都更新弹窗位置 viewer.scene.postRender.addEventListener(() => { // 实时把 3D 坐标 → 屏幕坐标 const canvasPosition = viewer.scene.cartesianToCanvasCoordinates(你的3D坐标); if (canvasPosition) { // 让弹窗跟着点位走 div.style.left = canvasPosition.x + 'px'; div.style.top = canvasPosition.y + 'px'; } });
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta content="width=device-width, initial-scale=1.0" /> <title>实体实时流畅移动</title> <!-- 引入Cesium库 --> <link /> <script></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: "Arial", sans-serif; background-color: #000; color: #e0e0e0; overflow: hidden; height: 100vh; } #cesiumContainer { width: 100%; height: 100%; position: absolute; } </style> </head> <body> <!-- Cesium容器 --> <div></div> <script> // 设置Cesium访问令牌(实际使用中需要替换为自己的token) Cesium.Ion.defaultAccessToken = "accessToken"; // 初始化地球视图 const viewer = new Cesium.Viewer("cesiumContainer", { sceneMode: Cesium.SceneMode.SCENE3D, animation: false, timeline: false, fullscreenButton: false, homeButton: false, geocoder: fal
http://www.jsqmd.com/news/499597/

相关文章:

  • Python之三大基本库——Pandas
  • python-flask高校失物招领平台38tp1
  • 基于S7-200 PLC和MCGS的电机转速闭环速度控制系统:带解释的梯形图程序、接线图原理图...
  • GLM-4.7-Flash性能实测:推理速度优化,响应更迅速
  • 三相光伏并网Matlab/Simulink仿真:MPPT控制与LCL滤波器应用
  • GLM-4v-9b多场景落地:教培机构用4090实现课件截图→知识点打标+习题生成
  • JAVA进阶-锁
  • 【Deer-flow】项目解读——subagent 调度
  • python数据结构-字符串
  • MMDOCIR: Benchmarking Multimodal Retrieval for Long Documents
  • APM使用LUA脚本发送实现遥控器PWM信号输出CAN协议信号
  • 广义预测控制(MPGC)在水下机器人中的应用——一场控制算法的探索
  • 卷积神经网络(CNN)在音频特征提取中的角色:SenseVoice-Small模型技术探秘
  • 圣女司幼幽-造相Z-Turbo保姆级教程:cat日志定位问题+Gradio端口映射调试
  • 机器学习创新探索
  • mysql,设置auto_increment
  • KCF算法中的公式如何带入以及C语言实现
  • 零基础搭建免费IP代理池:从原理到实战的保姆级指南
  • 快速入门!Xinference-v1.17.1部署实战:轻松搭建个人AI助手
  • PROJECT MOGFACE跨平台文档生成:替代Typora的智能Markdown写作体验
  • 从接口到业务协同:看懂 SAP 集成与 API 的底层逻辑
  • 神经符号AI:让机器人“能思考、会解释”的下一代控制范式
  • 082手机商城管理系统-ssm
  • LangGraph 核心概念
  • Stable Diffusion v1.5 在内容创作中的应用:快速生成文章插图与创意配图
  • 从接口目录到企业级集成中枢:读懂 SAP Business Accelerator Hub 的真正价值
  • Flet实战:教你用Python打造跨平台Todo应用(支持Win/Mac/Linux)
  • 程序员常见的职业病与预防
  • 从开题到答辩,这些毕业神器让你少走弯路
  • 从业务语义到可用应用:在 SAP Fiori 中创建自定义业务对象的完整思路