大家好,我是日拱一卒的攻城师不浪,致力于前沿科技探索,摸索小而美工作室,这是2025年输出的第21/100篇文章。
效果预览
在智慧城市、建筑信息模型(BIM
)、室内导航
等领域,楼层展开动画可以说是非常常见的一种功能需求了。
所以,今天我们来看一下在Cesium
中,如何实现的楼层展开与合并的动画功能。
源码请文末领取,还包含了Threejs的智慧园区(楼层动画展开)的源码
应用场景
-
建筑信息可视化:通过展开楼层,可以直观展示建筑
内部结构
和各楼层的分布情况。 -
紧急疏散演练:在消防安全培训中,可以清晰展示建筑的疏散通道和紧急出口位置。
-
室内导航:展开楼层后,用户可以更容易理解从一个楼层到另一个楼层的路径。
-
设施管理:对于物业管理人员,可以更直观地查看各楼层设备设施的分布状况。
-
房地产展示:销售人员可以通过展开楼层向潜在买家展示整栋建筑的结构和户型。
实现原理
该功能的实现原理核心在于通过调整三维模型的高度位置
来实现楼层的展开与合并效果。具体来说:
-
模型分层:将建筑模型分为多个楼层和一个楼顶,每个部分作为独立的
Entity
添加到Cesium
场景中。 -
位置控制:通过修改每个楼层实体的
position
属性,调整其高度来实现展开和合并效果。 -
数据记录:使用数组记录每个楼层的原始位置信息,便于后续进行位置变换。
核心代码解析
1. 初始化楼层
function initFloor() {
if (!viewer) return;
viewer.entities.removeAll();
floorArr = [];
const floor = parseInt(floorNum.value);
// 创建楼层
for (let i = 0; i < floor; i++) {
const position = Cesium.Cartesian3.fromDegrees(x, y, i * 3);
const entity = viewer.entities.add({
position: position,
model: {
uri: "//data.mars3d.cn/gltf/mars/floor/floor.glb",
scale: 1,
},
});
floorArr.push({
pos: [x, y, i * 3],
entity: entity,
});
}
// 创建楼顶
const position1 = Cesium.Cartesian3.fromDegrees(x, y, floor * 3);
const entity1 = viewer.entities.add({
position: position1,
model: {
uri: "//data.mars3d.cn/gltf/mars/floor/top.glb",
scale: 1,
},
});
floorArr.push({
pos: [x, y, floor * 3],
entity: entity1,
});
}
这段代码是楼层展开功能的基础。它主要做了以下几件事:
-
清除场景中已有的实体并重置楼层数组
-
根据用户输入的楼层数量(
floorNum
),循环创建楼层模型 -
每个楼层模型在垂直方向上间隔
3
个单位高度 -
使用
floorArr
数组记录每个楼层的原始坐标和对应的实体对象 -
最后创建楼顶,并同样将其添加到
floorArr
中
2. 楼层展开功能
function openFloorModel() {
for (let i = 0; i < floorArr.length; i++) {
const element = floorArr[i];
element.entity.position = Cesium.Cartesian3.fromDegrees(
element.pos[0],
element.pos[1],
element.pos[2] * 2
);
}
}
展开功能的核心是将每个楼层的高度值(element.pos[2]
)乘以2
,使楼层之间的间距变大,从而实现展开效果。这里的关键点是:
-
遍历
floorArr
数组中的每个楼层 -
保持楼层的经纬度不变,只修改高度值
-
使用
Cesium.Cartesian3.fromDegrees
方法将经纬度高度转换为Cesium
中的三维坐标
3. 楼层合并功能
function closeFloorModel() {
for (let i = 0; i < floorArr.length; i++) {
const element = floorArr[i];
element.entity.position = Cesium.Cartesian3.fromDegrees(
element.pos[0],
element.pos[1],
element.pos[2] / 1
);
}
}
合并功能则是将楼层恢复到原始位置,这里虽然代码中使用了element.pos[2] / 1
(实际上相当于不变),但原理是将每个楼层恢复到初始化时的高度位置。
4. 楼层抽出动画
楼层抽出动画原理,其实主要就是动态修改楼层entity的x,y坐标位置
,再结合浏览器的requestAnimationFrame
方法,添加缓动动画即可。
这部分功能暂时还未开放,放在了我的Cesium教程
里。
总结
OK,以上就是在Cesium中实现楼层展开与合并的一个技术方案与思路,实际业务过程中,我们就可以让建模师把楼层分成单独的entity
,然后我们去控制楼层的位置摆放,进而实现动画效果。
【不浪的Cesium案例集合】:github.com/tingyuxuan2…
【不浪的Three智慧园区开源】:github.com/tingyuxuan2…
如果开源对您有帮助,也欢迎帮我们点一个免费的star
,以鼓励和支持我们开源更多案例!
如有任何问题或需要进一步探讨,欢迎在评论区留言交流!
想系统学习Cesium的小伙伴儿,可以了解下不浪的教程
《Cesium从入门到实战》
,将Cesium的知识点进行串联,让不了解Cesium的小伙伴拥有一个完整的学习路线,并最终完成一个智慧城市
的完整项目,课程最近也更新了不少新内容,想了解+作者:brown_7778(备注来意)。
有需要进
可视化&Webgis交流群
可以加我:brown_7778(备注来意)。