功能实现:点击开始可实现在地图上绘制任意一点,并绕该点进行旋转,可通过el-slider控制旋转速度,点击停止按钮停止,并在点击开始后在刚刚停止位置继续旋转。
代码:
<div class="header-context">绕点飞行</div>
<button @click="startObserving">
<span ><img src="@/assets/img/start.png" alt="" /></span>开始
</button>
<button @click="stopObserving" <span><img src="@/assets/img/stop.png"
alt="" /></span>停止
</button>
<div>
<el-slider class="input-range" v-model="rollNumber" :show-tooltip="false" :min="1" :max="100" />
</div>
let distance; // 相机与目标点的距离
let angle; // 相机的旋转角度
let stopTime; // 停止时间
let initialHeading; // 初始朝向
let pitch; // 相机的俯仰角
let startTime; // 开始时间
let isRotating = false; // 标记是否正在旋转
let position; // 目标点位置
let entity; // 绘制的实体
let lastCameraState = {}; // 上次相机的状态
const rollNumber = ref(20); // 滚动速度
// 开始绕点飞行
const startObserving = () => {
if (isRotating) {
return; // 如果已经在旋转,则返回
}
if (position) {
// 如果已选择目标点,则开始绕点飞行
initialHeading = window.viewer.scene.camera.heading;
distance = Cesium.Cartesian3.distance(window.viewer.scene.camera.position, position);
pitch = window.viewer.scene.camera.pitch;
startTime = Cesium.JulianDate.fromDate(new Date());
stopTime = Cesium.JulianDate.addSeconds(startTime, Number.POSITIVE_INFINITY, new Cesium.JulianDate());
window.viewer.clock.startTime = startTime.clone();
window.viewer.clock.stopTime = stopTime.clone();
window.viewer.clock.currentTime = startTime.clone();
window.viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
window.viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;
window.viewer.clock.onTick.addEventListener(execution);
isRotating = true;
} else {
// 如果未选择目标点,则添加事件处理器选择目标点
let handler = new Cesium.ScreenSpaceEventHandler(window.viewer.scene.canvas);
handler.setInputAction(function (click) {
if (window.viewer.scene.mode !== Cesium.SceneMode.SCENE3D) {
return;
}
let cartesian = window.viewer.camera.pickEllipsoid(click.position);
if (cartesian) {
position = Cesium.Cartesian3.clone(cartesian);
entity = window.viewer.entities.add({
position: position,
point: {
pixelSize: 10,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
});
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
initialHeading = window.viewer.scene.camera.heading;
distance = Cesium.Cartesian3.distance(window.viewer.scene.camera.position, position);
pitch = window.viewer.scene.camera.pitch;
startTime = Cesium.JulianDate.fromDate(new Date());
stopTime = Cesium.JulianDate.addSeconds(startTime, Number.POSITIVE_INFINITY, new Cesium.JulianDate());
window.viewer.clock.startTime = startTime.clone();
window.viewer.clock.stopTime = stopTime.clone();
window.viewer.clock.currentTime = startTime.clone();
window.viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
window.viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;
window.viewer.clock.onTick.addEventListener(execution);
isRotating = true;
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
}
};
// 在每个时钟滴答时执行
const execution = () => {
var delTime = Cesium.JulianDate.secondsDifference(window.viewer.clock.currentTime, window.viewer.clock.startTime);
// 计算当前的航向增量
var headingIncrement = Cesium.Math.toRadians(delTime * rollNumber.value);
// 防止出现因速度减慢而导致的逆时针旋转
var heading = initialHeading + headingIncrement;
window.viewer.scene.camera.setView({
destination: position,
orientation: {
heading: heading,
pitch: pitch,
}
});
window.viewer.scene.camera.moveBackward(distance);
if (Cesium.JulianDate.compare(window.viewer.clock.currentTime, window.viewer.clock.stopTime) >= 0) {
window.viewer.clock.onTick.removeEventListener(execution);
isRotating = false;
}
};
// 监视 rollNumber 的变化
watch(rollNumber, (newVal, oldVal) => {
if (isRotating) {
// 记录当前航向和时间
var currentTime = Cesium.JulianDate.now();
var elapsed = Cesium.JulianDate.secondsDifference(currentTime, startTime);
initialHeading += Cesium.Math.toRadians(elapsed * oldVal);
startTime = currentTime;
window.viewer.clock.startTime = startTime.clone();
window.viewer.clock.currentTime = startTime.clone();
}
});
// 停止绕点飞行
const stopObserving = () => {
if (isRotating) {
window.viewer.clock.onTick.removeEventListener(execution);
isRotating = false;
window.viewer.clock.currentTime = stopTime.clone();
lastCameraState = {
position: window.viewer.scene.camera.position.clone(),
heading: window.viewer.scene.camera.heading,
pitch: window.viewer.scene.camera.pitch
};
}
};
// 移除绘制的实体
const removeEntity = () => {
if (entity) {
window.viewer.entities.remove(entity);
entity = null;
position = null;
}
};