前言
在Cesium的学习中,学会读文档十分重要!!!在这里附上中文文档Cesium中文文档1.95
在Cesium中,有一个类CumulusCloud是专门用来制作积云的。要通过点击的位置生成积云分4步,首先创建一个CloudCollection对象,然后绑定鼠标左击事件,获取屏幕点击处的位置,接着在此位置上加入体积云,最后绑定按钮点击事件就可以了。
一、创建CloudCollection对象
首先,我们先来了解一下CloudCollection对象,看看文档怎么说。
从文档可以知道,CloudCollection是体积云的集合,它可以将集合里的体积云渲染在场景中,其中可以通过option对像设置三个重要的属性,show是否显示云,默认为true,noiseDetail控制在用于渲染积云的预计算噪声纹理中捕获的细节量,值为2的幂,是number类型,noiseOffset对噪声纹理坐标应用平移以生成不同的数据。如果默认噪声不生成好看的云,则可以修改此设置,类型为Cartesian3。
const scene = viewer.scene; // 获取场景
let clouds = scene.primitives.add(
new Cesium.CloudCollection({
//noiseDetail: 32,// 噪声细节
//noiseOffset: new Cesium.Cartesian3(10, 20, 10), // 噪声偏移
})); // 添加云层
这里大家根据自己的需要修改noiseDetail和noiseOffset属性。
二、绑定鼠标左击事件
在Cesium中,处理屏幕相关的事件通过ScreenSpaceEventHandler来实现。
添加事件则是setInputAction函数。里面有三个参数,第一个就是当事件发生时执行的函数,第二个则是事件的类型,如鼠标左击,右击,移动等,第三个是可选的,表示正在按住的建。
这里,我们要绑定的是鼠标左击事件。 然后获取鼠标点击的位置。scene.pickPosition可以将屏幕坐标转换成笛卡尔三维坐标,但是,直接获取的坐标是一个贴地的坐标,这里我们先将其转换为地理坐标(经纬度),将其高程增加50000,方便我们浏览。
let drawHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
drawHandler.setInputAction((e) => { // 监听鼠标左键点击事件
const p = scene.pickPosition(e.position);
let carto_pt = Cesium.Cartographic.fromCartesian(p); //将笛卡尔坐标转换为地理坐标
let point = [Cesium.Math.toDegrees(carto_pt.longitude),Cesium.Math.toDegrees(carto_pt.latitude), carto_pt.height + 50000];
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
三、添加体积云
添加体积云我们通过CloudCollection的add方法,其options对象里的属性其实就是CumulusCloud的属性,我们可以根据这些参数为云的样式进行调整。
如brightness,获取或设置云的亮度,这可用于使云看起来更暗、更灰。
color,设置云的颜色。
maximumSize,获取或设置在广告牌上渲染的积云的最大尺寸。这定义了云可以出现的最大椭圆体体积。它不是保证特定的大小,而是指定云出现的边界,并且改变它会影响云的形状。 更改 maximumSize 的 z 值对云的外观有最显着的影响,因为它会改变云的深度,从而改变云形状纹理的采样位置。
position,设置云的笛卡尔三维坐标,在这里就是上面鼠标获取的位置。
scale,获取或设置积云广告牌的比例,以米为单位。 scale属性会影响广告牌的大小,但不会影响云的实际外观。
slice,获取或设置在广告牌上呈现的云的'切片',即为广告牌的外观选择的云的特定横截面。给定一个介于 0 和 1 之间的值,切片根据其在 z 方向上的最大尺寸指定要在云中相交的深度。
在这里,我写的是一朵粉色的云。为了使云朵好看些,你也可以写一些随机生成的代码。
let cloud = clouds.add({
show: true,
position: Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2]),//点位置
maximumSize: new Cesium.Cartesian3(20.0, 12.0, 8.0),//云朵在某个方向上纹理采样位置
scale: new Cesium.Cartesian2(100000, 100000),//云朵大小
slice: 0.36,//云朵切分比例
brightness: 0.8,//云朵亮度
color: Cesium.Color.PINK,//云朵颜色
});
四、绑定按钮点击事件
最后,我们将其写成一个函数,与按钮的点击事件绑定,当点击该按钮时开启绘制体积云事件。这里,我用的是element的按钮。
<el-button :icon="Location" @click="addCloud()"></el-button>
const addCloud = () => {
drawHandler.setInputAction((e) => { // 监听鼠标左键点击事件
const p = scene.pickPosition(e.position);
let carto_pt = Cesium.Cartographic.fromCartesian(p); //将笛卡尔坐标转换为地理坐标
let point = [Cesium.Math.toDegrees(carto_pt.longitude), Cesium.Math.toDegrees(carto_pt.latitude), carto_pt.height + 50000];
let cloud = clouds.add({
show: true,
position: Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2]),//点位置
maximumSize: new Cesium.Cartesian3(20.0, 12.0, 8.0),//云朵在某个方向上的采样位置
scale: new Cesium.Cartesian2(100000, 100000),//云朵缩放比例
slice: 0.36,//云朵切分比例
brightness: 0.8,//云朵亮度
color: Cesium.Color.PINK,//云朵颜色
});
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
五、资源的销毁
前面也说了,当不用的时候,记得及时销毁资源,这里我设置的是离开界面的时候销毁,你也可以写一个清除按钮。
onUnmounted(() => {
if (drawHandler) {
drawHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
drawHandler.destroy();
drawHandler = null;
}
if (clouds != null) {
clouds.removeAll();
scene.primitives.remove(clouds);
clouds = null;
}
});
笔记到这里就结束了,大家喜欢的话点个关注和免费的赞吧!