news 2025/12/25 8:44:45

2025cesium进阶教程(6)| webgis智慧城市开发,3DTiles 卷帘对比效果(附完整源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
2025cesium进阶教程(6)| webgis智慧城市开发,3DTiles 卷帘对比效果(附完整源码)

在 Cesium 可视化开发中,卷帘对比是常用功能,可用于 3D Tiles 模型、影像图层的左右分屏对比,支持动态调整分割比例。

本文基于 Cesium 1.41+ 版本的SplitDirection特性,从核心原理、到代码实现,带着大家实现一下cesium卷帘对比效果。欢迎大家一起交流学习。

2025cesium进阶教程持续更新中...

前篇回顾:

2025cesium进阶教程|Cesium 天气特效实现:从 ShaderToy 移植下雪效果的完整方案_shadertoy和cesium如何结合-CSDN博客https://blog.csdn.net/yaogis888/article/details/154843181?spm=1001.2014.3001.5502Cesium进阶教程(2)|基于 Cesium 后处理Post Processing的图形绘制(上)-CSDN博客https://blog.csdn.net/yaogis888/article/details/154994782?spm=1001.2014.3001.5502Cesium进阶教程(2)|基于 Cesium 后处理Post Processing的图形绘制(下)-CSDN博客https://blog.csdn.net/yaogis888/article/details/154995091?spm=1001.2014.3001.55022025Cesium进阶教程(3) 发光流动线实例讲解,实现自定义 MaterialProperty(上)_cesium.createpropertydescriptor-CSDN博客https://blog.csdn.net/yaogis888/article/details/155226305?spm=1001.2014.3001.55012025Cesium进阶教程(3) 发光流动线实例讲解,实现自定义 MaterialProperty(下)_cesium流动线-CSDN博客https://blog.csdn.net/yaogis888/article/details/155227354?spm=1001.2014.3001.55012025Cesium进阶教程(4)| 动态响应的发光流动线实例讲解-CSDN博客https://blog.csdn.net/yaogis888/article/details/155483412?spm=1001.2014.3001.55012025Cesium进阶教程(5)| webgis智慧城市开发,大屏可视化行政区高亮-CSDN博客https://blog.csdn.net/yaogis888/article/details/155575623?spm=1001.2014.3001.5501

一、核心功能与原理概括

1.SplitDirection 核心功能

  • 支持 3D Tiles / 影像图层的左右分屏对比,指定目标图层仅在左侧或右侧显示;

  • 提供可视化分割线,支持鼠标拖拽交互,动态调整分屏比例;

  • 解决拖拽偏移误差,确保分割线移动流畅、位置精准。

2. 实现原理

  • 核心依赖 Cesium 两个关键配置:splitDirection(指定图层显示侧:左 / 右)和splitPosition(控制分割位置,取值 0-1);

  • 通过创建 DOM 元素作为分割线,绑定鼠标 “按下 - 移动 - 抬起” 事件,动态计算并更新splitPosition,实现分屏比例的实时调整;

  • 引入偏移修正逻辑,通过记录鼠标初始点击位置,避免拖拽时分割线突然跳转。

二、效果实现:

1:依赖引入与场景初始化

使用Cesium库创建一个3D地球视图,并配置了基础控件和地形加载功能。同时引入dat.gui库(通常用于调试参数调节),并设置Cesium的Ion访问令牌。

  • Cesium初始化配置
import*asCesiumfrom"cesium";import*asdatfrom"dat.gui";import{ token }from"../lib/token";Cesium.Ion.defaultAccessToken= token;constviewer =newCesium.Viewer("container", {timeline:true,// 显示时间线控件animation:false,// 隐藏动画控件baseLayerPicker:false,// 隐藏底图切换控件infoBox:false,// 隐藏要素点击信息框selectionIndicator:false,// 隐藏选中元素指示器homeButton:false,// 隐藏复位按钮fullscreenButton:false,// 隐藏全屏按钮geocoder:false,// 隐藏地理编码(搜索)控件sceneModePicker:false,// 隐藏二三维模式切换控件shouldAnimate:true,// 启用动画效果(必填)navigationHelpButton:false,// 隐藏导航帮助按钮
  • 地形加载配置
terrainProvider:newCesium.CesiumTerrainProvider({url:Cesium.IonResource.fromAssetId(1),// 加载地形(可选)}), });
  • 关键渲染设置
viewer.scene.globe.depthTestAgainstTerrain=true;// 开启地形深度测试

2:3D Tiles 加载与卷帘基础配置

使用CesiumJS库加载并控制一个3D Tiles模型,同时实现卷帘对比效果。以下是逐部分解析:

  • 加载3D Tiles模型
consttileset =newCesium.Cesium3DTileset({url:"http://localhost:666/model/AGI_HQ/tileset.json",// 3D Tiles 模型地址}); viewer.scene.primitives.add(tileset);// 将模型添加到场景
  • 等待模型加载完成
awaittileset.readyPromise;
  • 设置模型位置
// 定义模型位置(经纬度:114.3°E,30.5°N,高度 30m)constmodelMatrix =Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(114.3,30.5,30.0) ); tileset._root.transform= modelMatrix;// 应用模型位置变换
  • 视角控制
viewer.zoomTo(tileset);
  • 卷帘效果实现
// 核心卷帘参数配置tileset.splitDirection=Cesium.SplitDirection.LEFT; viewer.scene.splitPosition=0.5;

3:可视化分割线创建

于在网页中创建一条3:1比例的可视化分割线,支持自定义颜色和样式。

constslider =document.createElement("div");document.querySelector("#container").appendChild(slider); slider.id="slider";// 分割线样式配置slider.style.display="block"; slider.style.position="absolute";// 绝对定位(相对于 container)slider.style.top="0"; slider.style.height="100%";// 高度占满容器slider.style.width="5px";// 分割线宽度(便于点击拖拽)slider.style.backgroundColor="#fff";// 白色分割线slider.style.cursor="col-resize";// 鼠标悬浮显示左右拖拽样式slider.style.zIndex="1000";// 确保分割线在最上层slider.style.left="50%";// 初始位置与 splitPosition 一致

4:鼠标拖拽事件绑定(交互逻辑实现)

基于Cesium.js的屏幕分割交互功能,通过鼠标拖拽控制场景分屏比例。核心功能包括:拖拽状态管理、分割位置计算、界面元素同步更新。

  • 变量定义
consthandler =newCesium.ScreenSpaceEventHandler(slider);letisDragging =false;// 拖拽状态标记(默认未拖拽)letstartX;// 记录鼠标按下时的初始 X 坐标(修正拖拽偏移)
  • 鼠标按下事件
// 鼠标左键按下事件(开启拖拽)handler.setInputAction((movement) =>{ isDragging =true; startX = movement.position.x;// 记录鼠标按下时的初始 X 坐标},Cesium.ScreenSpaceEventType.LEFT_DOWN);
  • 鼠标移动事件
// 鼠标移动事件(更新分割位置)handler.setInputAction((movement) =>{if(!isDragging)return;// 未拖拽时,不执行任何操作constendPosition = movement.endPosition;// 鼠标当前位置// 计算新的分割位置(0-1 范围)constsplitPosition = (slider.offsetLeft+ endPosition.x- startX) / slider.parentElement.offsetWidth;// 限制 splitPosition 范围在 0-1 之间,避免超出屏幕constclampedSplitPosition =Cesium.Math.clamp(splitPosition,0,1);// 更新场景分屏位置和分割线样式viewer.scene.splitPosition= clampedSplitPosition; slider.style.left=`${clampedSplitPosition *100}%`; },Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  • 鼠标释放事件
// 鼠标左键抬起事件(结束拖拽)handler.setInputAction(() =>{ isDragging =false; },Cesium.ScreenSpaceEventType.LEFT_UP);

看不明白没关系,点这里可以查看视频解析👇

2025Cesium进阶教程(5)| webgis智慧城市开发,大屏可视化行政区高亮-CSDN博客https://blog.csdn.net/yaogis888/article/details/155575623?spm=1001.2014.3001.5501

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!