Cesium.js(SuperMap iClient3D for Cesium)进行三维场景展示和图层动画

1):参考API文档:SuperMap iClient3D for Cesium 开发指南

2):官网示例:support.supermap.com.cn:8090/webgl/Cesium/examples/webgl/examples.html#layer

3):SuperMap iServer:欢迎使用 SuperMap iServer 11i(2022) (supermapol.com)

1.HTML部分

javascript 复制代码
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
	<meta name="viewport"
		content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
	<title>图层动画</title>
	<link href="../../Build/Cesium/Widgets/widgets.css" rel="stylesheet">
	<link href="./css/pretty.css" rel="stylesheet">
	<script src="./js/jquery.min.js"></script>
	<script src="./js/config.js"></script>
	<script type="text/javascript" src="../../Build/Cesium/Cesium.js"></script>
</head>
<body>
	<div id="cesiumContainer"></div>
	<div id='loadingbar' class="spinner">
		<div class="spinner-container container1">...</div>
		<div class="spinner-container container2">...</div>
		<div class="spinner-container container3">...</div>
	</div>
	<div id="toolbar" class="param-container tool-bar">
		<button type="button" id="start" class="button black">动画开始</button>
	</div>
  • link 标签 : 引入了 Cesium 的样式表 (widgets.css) 和自定义的样式表 (pretty.css) 以美化界面。

  • script 标签 : 通过 jQuery、项目配置文件 (config.js)、Cesium 库 (Cesium.js) 来加载 JavaScript 功能。 config.js 很可能包含 API 密钥和场景相关的配置。

  • cesiumContainer : 这是 Cesium 三维地球容器,Cesium.js 会将 3D 场景渲染到这个 div 中。

  • loadingbar: 页面加载时的旋转加载动画,用户等待场景加载时显示,加载完后会被移除。

  • toolbar: 工具栏,包含一个按钮 "动画开始",用户点击后会启动图层动画。

2.JS部分

javascript 复制代码
var viewer = "";
function onload(Cesium) {
	viewer = new Cesium.Viewer('cesiumContainer');
  • viewer : 全局变量,用来存储 Cesium 的 Viewer 实例,它是 Cesium 应用的核心,用于管理和渲染 3D 场景。

  • Cesium.Viewer : 通过创建 Viewer 实例,将 Cesium 场景附加到 cesiumContainer 上。

3.场景和视角设置

javascript 复制代码
scene.camera.setView({
	destination: new Cesium.Cartesian3( -2179784.959673108, 4380066.04070574, 4092037.131416261),
	orientation: {
		heading: 3.1380738694592583,
		pitch: -0.2798725811830971,
		roll: 6.283185307179586
	}
});

4.图层加载

var promise = scene.open(URL_CONFIG.SCENE_ANIMATION);
var layerName = ["第一层", "第二层", "第三层", "设备", "第四层", "墙01@Model - 副本", "屋顶@Model - 副本"];
var layerIndex = [0, 1, 2, 3, 4, 5, 6];
  • 使用 scene.open 打开一个包含动画的场景文件,场景文件地址从 config.js 中读取。

  • layerName 是一个包含图层名称的数组,layerIndex 是图层的索引数组,用于后续的图层动画。

5.动画

javascript 复制代码
$("#start").click(function () {
	viewer.camera.speedRatio = 0.25;
	var viewCenter = new Cesium.Cartesian3(-2179804.7971194154, 4380105.068829024, 4091940.5042720092);				
	setAnimation(sequenceLayers, index);
	viewer.camera.flyCircle(viewCenter);					
});
  • 点击 "动画开始" 按钮后,相机会围绕 viewCenter 坐标进行循环飞行,同时调用 setAnimation 函数启动图层动画。

  • speedRatio 用于调整相机的旋转速度。

6.图层动画函数

javascript 复制代码
function setAnimation(layers, index) {
	layers[index].visible = true;
	return layers[index].setAnimation({
		keyframes: {
			'100%': {
				translation: Cesium.Cartesian3.fromDegrees(layers[index].lon, layers[index].lat, 0)
			},
			'0%': {
				translation: Cesium.Cartesian3.fromDegrees(layers[index].lon, layers[index].lat, 50)
			}
		},
		duration: 2.0
	}).then(function () {
		if ((index + 1) >= animationAllLayer.length) {
			return;
		}
		return setAnimation(animationAllLayer, index + 1);
	})
}
  • setAnimation 函数通过 setAnimation 方法为图层设置关键帧动画,图层在 2 秒内从 50 米高处下降到地面。

  • 动画完成后,递归调用 setAnimation,以顺序播放多个图层的动画。

7.代码展示

javascript 复制代码
<body>
	<div id="cesiumContainer"></div>
	<div id='loadingbar' class="spinner">
		<div class="spinner-container container1">
			<div class="circle1"></div>
			<div class="circle2"></div>
			<div class="circle3"></div>
			<div class="circle4"></div>
		</div>
		<div class="spinner-container container2">
			<div class="circle1"></div>
			<div class="circle2"></div>
			<div class="circle3"></div>
			<div class="circle4"></div>
		</div>
		<div class="spinner-container container3">
			<div class="circle1"></div>
			<div class="circle2"></div>
			<div class="circle3"></div>
			<div class="circle4"></div>
		</div>
	</div>
	<div id="toolbar" class="param-container tool-bar">
		<button type="button" id="start" class="button black">动画开始</button>
	</div>
	<script>
		var viewer = "";
		function onload(Cesium) {
			viewer = new Cesium.Viewer('cesiumContainer');
			viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({
				url: 'https://dev.virtualearth.net',
				mapStyle: Cesium.BingMapsStyle.AERIAL,
				key: URL_CONFIG.BING_MAP_KEY
			}));

			var scene = viewer.scene;
			viewer.scene.globe.show = false;
			scene.debugShowFramesPerSecond = true;
			scene.hdrEnabled = false;
			scene.sun.show = true;
			viewer.scene.postProcessStages.mxaa = false;
			viewer.scene.postProcessStages.fxaa.enabled = true;
			scene.lightSource.ambientLightColor = new Cesium.Color(0.65, 0.65, 0.65, 1);
			var promise = scene.open(URL_CONFIG.SCENE_ANIMATION);
			var animationLayer = [];
			var sequenceLayers = [];
			var layerName = ["第一层", "第二层", "第三层", "设备", "第四层", "墙01@Model - 副本", "屋顶@Model - 副本"];
			var layerIndex = [0, 1, 2, 3, 4, 5, 6]; //索引数组
			var scratchWindowPosition = new Cesium.Cartesian2();
			Cesium.when(promise, function (layers) {
				//相机定位
				scene.camera.setView({
					destination: new Cesium.Cartesian3( -2179784.959673108, 4380066.04070574, 4092037.131416261),
					orientation: {
						heading: 3.1380738694592583,
						pitch: -0.2798725811830971,
						roll: 6.283185307179586
					}
				});
				for (var i = 0; i < layers.length; i++) {
					layers[i].visible = false;
				}

				for (var j = 0; j < layerName.length; j++) {
					var layer = scene.layers.find(layerName[j]);
					animationLayer.push(layer);
				}
				for (var i = 0; i < animationLayer.length; i++) {
					sequenceLayers[layerIndex[i]] = animationLayer[i];
				}


				var index = 0;
				$("#start").click(function () {
					// viewer.scene.camera.flyCircleLoop = true; //是否循环旋转
					viewer.camera.speedRatio = 0.25;
					//旋转点
					var viewCenter =  new Cesium.Cartesian3(-2179804.7971194154, 4380105.068829024, 4091940.5042720092);				
					setAnimation(sequenceLayers, index);
					viewer.camera.flyCircle(viewCenter);					
				});

				$('#loadingbar').remove();
			});

			var animationAllLayer;

			function setAnimation(layers, index) {
				animationAllLayer = layers;
				layers[index].visible = true;				
				return layers[index].setAnimation({				
					keyframes: {
						'100%': {
							translation: Cesium.Cartesian3.fromDegrees(layers[index].lon, layers[index].lat, 0)
						},
						'0%': {
							translation: Cesium.Cartesian3.fromDegrees(layers[index].lon, layers[index].lat, 50),
						}
					},
					duration: 2.0
				}).then(function () {
					if ((index + 1) >= animationAllLayer.length) {
						return;
					}
					return setAnimation(animationAllLayer, index + 1);
				})
			}
		}
		if (typeof Cesium !== 'undefined') {
			window.startupCalled = true;
			onload(Cesium);
		}
	</script>
</body>

8.效果展示

相关推荐
前端Hardy1 天前
HTML&CSS:数据卡片可以这样设计
前端·javascript·css·3d·html
小彭努力中1 天前
138. CSS3DRenderer渲染HTML标签
前端·深度学习·3d·webgl·three.js
AI生成未来1 天前
斯坦福&UC伯克利开源突破性视觉场景生成与编辑技术,精准描绘3D/4D世界!
3d·3d场景·4d
汪洪墩2 天前
【Mars3d】实现这个地图能靠左,不居中的样式效果
前端·javascript·vue.js·3d·webgl·cesium
Bearnaise2 天前
GaussianDreamer: Fast Generation from Text to 3D Gaussians——点云论文阅读(11)
论文阅读·人工智能·python·深度学习·opencv·计算机视觉·3d
智驾机器人技术前线2 天前
近期两篇NeRF/3DGS-based SLAM方案赏析:TS-SLAM and MBA-SLAM
3d·slam·nerf·3dgs
Tianwen_Burning2 天前
halcon3d disparity_image_to_xyz非常重要的算子及使用条件
算法·3d
光学测量小菜鸡3 天前
OpenCV双目立体视觉重建
opencv·3d·双目相机·结构光·sgbm
豆包MarsCode3 天前
基于豆包MarsCode 和 Threejs 实现3D地图可视化
大数据·开发语言·人工智能·python·3d·程序员
工业3D_大熊3 天前
3D数据格式转换工具HOOPS Exchange如何在读取CAD文件时处理镶嵌数据?
java·linux·c++·windows·macos·3d·c#