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部分
<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部分
var viewer = "";
function onload(Cesium) {viewer = new Cesium.Viewer('cesiumContainer');
-
viewer
: 全局变量,用来存储 Cesium 的Viewer
实例,它是 Cesium 应用的核心,用于管理和渲染 3D 场景。 -
Cesium.Viewer
: 通过创建Viewer
实例,将 Cesium 场景附加到cesiumContainer
上。
3.场景和视角设置
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.动画
$("#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.图层动画函数
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.代码展示
<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>