(1)相机绕点旋转
相机视点固定,相机位置移动,保持相同的距离绕该视点旋转,可用于对物体的360度浏览。
//使用useState更新isrotate,用于控制旋转启动与暂停
const [isrotate,setIsrotate] = useState(false)
const rotateIntervalRef = useRef(null);
function rotatecam(){
var viewer = viewerRef.current
if (isrotate) {
clearInterval(rotateIntervalRef.current);
}
else {
var center = new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2);
var cartesian = viewer.scene.camera.pickEllipsoid(center)
if (cartesian) {
var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
var longitude = Cesium.Math.toDegrees(cartographic.longitude);
var latitude = Cesium.Math.toDegrees(cartographic.latitude);
}
var position = Cesium.Cartesian3.fromDegrees(longitude,latitude,0);
var pitch = viewer.camera.pitch
var angle = 360 / 30;
var distance = Cesium.Cartesian3.distance(cartesian,viewer.camera.position)
var startTime = Cesium.JulianDate.fromDate(new Date());
viewer.clock.startTime = startTime.clone();
viewer.clock.currentTime = startTime.clone();
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;
// 相机的当前heading
var initialHeading = viewer.camera.heading;
rotateIntervalRef.current = setInterval(() => {
var delTime = Cesium.JulianDate.secondsDifference(
viewer.clock.currentTime,
viewer.clock.startTime
);
var heading = initialHeading - Cesium.Math.toRadians(delTime * angle);
viewer.scene.camera.setView({
destination: position,
orientation: {
heading: heading,
pitch: pitch,
},
});
viewer.scene.camera.moveBackward(distance);
}, 1000 / 30);
}
setIsrotate(isrotate=>!isrotate)
}
绕点旋转
(2)固定位置旋转(第一人称效果)
相机位置不动,镜头朝向改变,可用于浏览物体周围景观。
const [isrotate,setIsrotate] = useState(false)
const rotateIntervalRef = useRef(null);
function rotate(){
var viewer = viewerRef.current
if (isrotate) {
clearInterval(rotateIntervalRef.current);
}
else {
var position = viewer.camera.position;
var pitch = viewer.camera.pitch
var angle = 360 / 30;
var startTime = Cesium.JulianDate.fromDate(new Date());
viewer.clock.startTime = startTime.clone();
viewer.clock.currentTime = startTime.clone();
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;
// 相机的当前heading
var initialHeading = viewer.camera.heading;
rotateIntervalRef.current = setInterval(() => {
var delTime = Cesium.JulianDate.secondsDifference(
viewer.clock.currentTime,
viewer.clock.startTime
);
var heading = initialHeading - Cesium.Math.toRadians(delTime * angle);
viewer.scene.camera.setView({
destination: position,
orientation: {
heading: heading,
pitch: pitch,
},
});
}, 1000 / 30);
}
setIsrotate(isrotate=>!isrotate)
}
视角自动旋转观察四周
若需要实现手动上下左右旋转浏览,核心代码如下:
function rotor(){
var viewer = viewerRef.current
var startPos;
//取消视图的一些浏览功能
viewer.scene.screenSpaceCameraController.enableRotate = false;
viewer.scene.screenSpaceCameraController.enableTranslate = false;
viewer.scene.screenSpaceCameraController.enableTilt = false;
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(event) {
startPos = new Cesium.Cartesian2(event.position.x,event.position.y)
},Cesium.ScreenSpaceEventType.LEFT_DOWN)
handler.setInputAction(function(event) {
if(!startPos){
return
}
var endPos = new Cesium.Cartesian2(event.endPosition.x,event.endPosition.y)
var move = Cesium.Cartesian2.subtract(endPos,startPos,new Cesium.Cartesian2())
var x_move = move.x;
var y_move = move.y;
viewer.camera.setView({
destination:viewer.camera.position,
orientation:{
heading: viewer.camera.heading+Cesium.Math.toRadians(x_move),
pitch: viewer.camera.pitch+Cesium.Math.toRadians(-y_move)
}
})
startPos = endPos;
},Cesium.ScreenSpaceEventType.MOUSE_MOVE)
handler.setInputAction(function(event) {
startPos = undefined
},Cesium.ScreenSpaceEventType.LEFT_UP)
}