在 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