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

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

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

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

3:可视化分割线创建

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

javascript 复制代码
const slider = 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的屏幕分割交互功能,通过鼠标拖拽控制场景分屏比例。核心功能包括:拖拽状态管理、分割位置计算、界面元素同步更新。

变量定义
javascript 复制代码
const handler = new Cesium.ScreenSpaceEventHandler(slider);
let isDragging = false; // 拖拽状态标记(默认未拖拽)
let startX; // 记录鼠标按下时的初始 X 坐标(修正拖拽偏移)
鼠标按下事件
javascript 复制代码
// 鼠标左键按下事件(开启拖拽)
handler.setInputAction((movement) => {
  isDragging = true;
  startX = movement.position.x; // 记录鼠标按下时的初始 X 坐标
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
鼠标移动事件
javascript 复制代码
// 鼠标移动事件(更新分割位置)
handler.setInputAction((movement) => {
  if (!isDragging) return; // 未拖拽时,不执行任何操作
  const endPosition = movement.endPosition; // 鼠标当前位置
  // 计算新的分割位置(0-1 范围)
  const splitPosition = (slider.offsetLeft + endPosition.x - startX) / slider.parentElement.offsetWidth;
  // 限制 splitPosition 范围在 0-1 之间,避免超出屏幕
  const clampedSplitPosition = Cesium.Math.clamp(splitPosition, 0, 1);

  // 更新场景分屏位置和分割线样式
  viewer.scene.splitPosition = clampedSplitPosition;
  slider.style.left = `${clampedSplitPosition * 100}%`;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
鼠标释放事件
javascript 复制代码
// 鼠标左键抬起事件(结束拖拽)
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

相关推荐
NueXini2 小时前
Unity 3D MMO RPG手游征服2GB设备之历程
3d·unity·性能优化·游戏引擎·优化·rpg·mmo
致Great2 小时前
什么是智能体工程Agent Engineering?让 AI从“能跑“到“敢用“的关键
人工智能·microsoft
江沉晚呤时3 小时前
使用 C# 和 Semantic Kernel 构建 PDF 向量搜索系统:从文本提取到语义搜索
jvm·人工智能·microsoft·chatgpt·c#
刘 怼怼3 小时前
FreeXGIS + Cesium 实现三维场景多标记点与自定义交互标牌开发
microsoft·交互
自在极意功。15 小时前
Web开发中的分层解耦
java·microsoft·web开发·解耦
txzz888816 小时前
网络应用netstart命令
网络·windows·计算机网络·microsoft
元境16 小时前
“3D数字内容创新发展高峰论坛”在京成功举办,多项重要合作与课题启动
3d
song50117 小时前
鸿蒙 Flutter 图像识别进阶:物体分类与花卉识别(含离线模型)
人工智能·分布式·python·flutter·3d·华为·分类
中维ZWPD20 小时前
工程行业数智化转型:挑战与破局之路
大数据·人工智能·科技·物联网·3d