接触Cesium这个框架也有一周的时间了吧,学到了不少东西,网上关于这个框架的教程也比较少,总之,连滚带爬,也能凑合写出来一个demo把。
下面就是一个根据官网几个Demo学习后自己写的一个demo。东西比较简陋,还有很多可以扩展的地方~~比如动态设置小车速度,视角跟随等等
效果图
通过键盘上的方向键来控制小车方向,前进,退后。
大概思路如下:
1、添加数据模型
2、监听键盘按键
3、计算坐标
4、移动小车
初始化
<body>
<div id="cesiumDemo"></div>
<script type="text/javascript">
let view = new Cesium.Viewer('cesiumDemo',{
baseLayerPicker: false,
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
})
});
// 小车旋转角度
let radian = Cesium.Math.toRadians(3.0);
// 小车的速度
let speed = 60;
// 速度矢量
let speedVector = new Cesium.Cartesian3();
let scene = view.scene;
// 起始位置
let position = Cesium.Cartesian3.fromDegrees(116.080591,39.919141,0);
// 用于设置小车方向
let hpRoll = new Cesium.HeadingPitchRoll();
let fixedFrameTransforms = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west');
</script>
</body>
添加3d模型
这里没有用entity方式添加组件,是因为使用entity不方便下面计算坐标。模型为官网架包里的模型。
let carPrimitive = scene.primitives.add(Cesium.Model.fromGltf({
url: '../Apps/SampleData/models/CesiumMilkTruck/CesiumMilkTruck-kmc.glb',
modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransforms),
minimumPixelSize:128
}));
监听键盘按键
// 小车状态标志
let flag = {
moveUp:false,
moveDown:false,
moveLeft:false,
moveRight:false
};
// 根据键盘按键返回标志
function setFlagStatus(key,value) {
switch (key.keyCode){
case 37:
// 左
flag.moveLeft = value;
break;
case 38:
// 上
flag.moveUp = value;
break;
case 39:
// 右
flag.moveRight = value;
break;
case 40:
flag.moveDown = value;
// 下
break;
}
}
document.addEventListener('keydown',(e)=>{
setFlagStatus(e, true);
});
document.addEventListener('keyup',(e)=>{
setFlagStatus(e, false);
});
监听帧
view.clock.onTick.addEventListener((clock)=>{
if(flag.moveUp){
if(flag.moveLeft){
hpRoll.heading -= radian;
}
if(flag.moveRight){
hpRoll.heading += radian;
}
moveCar(true);
}
if(flag.moveDown){
if(flag.moveLeft){
hpRoll.heading -= radian;
}
if(flag.moveRight){
hpRoll.heading += radian;
}
moveCar(false);
}
});
// 移动小车
function moveCar(isUP) {
// 计算速度矩阵
if(isUP>0){
speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X,speed,speedVector);
}else{
speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X,-speed,speedVector);
}
// 根据速度计算出下一个位置的坐标
position = Cesium.Matrix4.multiplyByPoint(carPrimitive.modelMatrix ,speedVector, position);
// 小车移动
Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransforms, carPrimitive.modelMatrix);
}
完整代码
<body>
<div id="cesiumDemo"></div>
<script type="text/javascript">
let view = new Cesium.Viewer('cesiumDemo',{
baseLayerPicker: false,
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
})
});
// 小车旋转角度
let radian = Cesium.Math.toRadians(3.0);
// 小车的速度
let speed = 60;
// 速度矢量
let speedVector = new Cesium.Cartesian3();
let scene = view.scene;
// 起始位置
let position = Cesium.Cartesian3.fromDegrees(116.080591,39.919141,0);
// 用于设置小车方向
let hpRoll = new Cesium.HeadingPitchRoll();
let fixedFrameTransforms = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west');
// 添加小车模型
let carPrimitive = scene.primitives.add(Cesium.Model.fromGltf({
url: '../Apps/SampleData/models/CesiumMilkTruck/CesiumMilkTruck-kmc.glb',
modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransforms),
minimumPixelSize:128
}));
// 小车状态标志
let flag = {
moveUp:false,
moveDown:false,
moveLeft:false,
moveRight:false
};
// 根据键盘按键返回标志
function setFlagStatus(key,value) {
switch (key.keyCode){
case 37:
// 左
flag.moveLeft = value;
break;
case 38:
// 上
flag.moveUp = value;
break;
case 39:
// 右
flag.moveRight = value;
break;
case 40:
flag.moveDown = value;
// 下
break;
}
}
document.addEventListener('keydown',(e)=>{
setFlagStatus(e, true);
});
document.addEventListener('keyup',(e)=>{
setFlagStatus(e, false);
});
// 对帧添加监听事件
view.clock.onTick.addEventListener((clock)=>{
if(flag.moveUp){
if(flag.moveLeft){
hpRoll.heading -= radian;
}
if(flag.moveRight){
hpRoll.heading += radian;
}
moveCar(true);
}
if(flag.moveDown){
if(flag.moveLeft){
hpRoll.heading -= radian;
}
if(flag.moveRight){
hpRoll.heading += radian;
}
moveCar(false);
}
});
// 移动小车
function moveCar(isUP) {
// 计算速度矩阵
if(isUP>0){
speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X,speed,speedVector);
}else{
speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X,-speed,speedVector);
}
// 根据速度计算出下一个位置的坐标
position = Cesium.Matrix4.multiplyByPoint(carPrimitive.modelMatrix ,speedVector, position);
// 小车移动
Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransforms, carPrimitive.modelMatrix);
}
</script>
</body>