Cesium学习笔记(四): 相机(camera)

9 篇文章 3 订阅
9 篇文章 0 订阅

相机可以控制我们在场景中的视野,默认的,相机操作是这样的:

  • 左键单击并拖动 - 移动整个地图
  • 右键单击并拖动 - 放大和缩小相机。
  • 中轮滚动 - 也可以放大和缩小相机。
  • 中间点击并拖动 - 围绕地球表面的点旋转相机。

我们可以自己给相机设置位置

var point = Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0);
camera.setView({
    destination : point,
    orientation: {
        heading : Cesium.Math.toRadians(0.0), //默认值
        pitch : Cesium.Math.toRadians(-90.0), // 默认值
        roll : 0.0 //默认值
    }
});

这里写图片描述

可以看出来,我们加载的是一个点,这个视野也是从这个点看去的视野,我们也可以加载一个矩形,也就是整个视野区域
//他需要西,南,东,北四个度数来构成
var rectangle = Cesium.Rectangle.fromDegrees(0.0, 20.0, 10.0, 30.0);
camera.setView({
    destination : point,
    orientation: {
        heading : Cesium.Math.toRadians(0.0), //默认值
        pitch : Cesium.Math.toRadians(-90.0), // 默认值
        roll : 0.0 //默认值
    }
});

这里写图片描述

你现在所看到的区域就是我们加载的这个矩形了

现在,我们来尝试自己覆写镜头移动。

首先肯定是先把原有的给禁止掉

var viewer = new Cesium.Viewer("cesiumContainer");
var scene = viewer.scene;
var canvas = viewer.canvas;
canvas.setAttribute('tabindex', '0'); // 需要把焦点放在画布上
canvas.onclick = function() {
    canvas.focus();
};
//这个椭球形就是地球了
var ellipsoid = viewer.scene.globe.ellipsoid;

// 禁止默认的事件
scene.screenSpaceCameraController.enableRotate = false;
scene.screenSpaceCameraController.enableTranslate = false;
scene.screenSpaceCameraController.enableZoom = false;
scene.screenSpaceCameraController.enableTilt = false;
scene.screenSpaceCameraController.enableLook = false;

然后再创建我们用来记录鼠标位置和键盘点击情况的变量

//存储鼠标位置的变量
var startMousePosition;
var mousePosition;

var flags = {
    //记录是否在查看地图,也就是记录是否点击了鼠标或键盘
    looking : false,
    //记录键盘的前后上下左右
    moveForward : false,
    moveBackward : false,
    moveUp : false,
    moveDown : false,
    moveLeft : false,
    moveRight : false
};

继续为键盘的wasdqe几个键设置相机移动效果

//判断键盘的输入
function getFlagForKeyCode(keyCode) {
    switch (keyCode) {
    case 'W'.charCodeAt(0):
        return 'moveUp';
    case 'S'.charCodeAt(0):
        return 'moveDown';
    case 'Q'.charCodeAt(0):
        return 'moveForward';
    case 'E'.charCodeAt(0):
        return 'moveBackward';
    case 'D'.charCodeAt(0):
        return 'moveRight';
    case 'A'.charCodeAt(0):
        return 'moveLeft';
    default:
        return undefined;
    }
}
//获得键盘keydown事件
document.addEventListener('keydown', function(e) {
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = true;
    }
}, false);
//获得键盘keyup事件
document.addEventListener('keyup', function(e) {
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = false;
    }
}, false);

别忘了,还有鼠标

//监听用户的输入
var handler = new Cesium.ScreenSpaceEventHandler(canvas);
//当鼠标左键按下时执行(拿到鼠标按下时的位置)
handler.setInputAction(function(movement) {
    flags.looking = true;
    mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
//当鼠标移动时执行(拿到鼠标抬起时的位置)
handler.setInputAction(function(movement) {
    mousePosition = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//当鼠标左键抬起时执行
handler.setInputAction(function(position) {
    flags.looking = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);

最后根据我们接收的鼠标和键盘的输入,来实现真正的相机移动

//更新相机
viewer.clock.onTick.addEventListener(function(clock) {
    var camera = viewer.camera;
    //当按下鼠标左键时
    if (flags.looking) {
        var width = canvas.clientWidth;
        var height = canvas.clientHeight;

        // 鼠标滑动的距离的xy/网页可见区域的宽或者高
        var x = (mousePosition.x - startMousePosition.x) / width;
        var y = -(mousePosition.y - startMousePosition.y) / height;
        //这就是决定相机移动速度的参数
        var lookFactor = 0.05;
        //相机移动
        camera.lookRight(x * lookFactor);
        camera.lookUp(y * lookFactor);
    }

    // 镜头移动的速率基于镜头离地球的高度
    var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
    var moveRate = cameraHeight / 100.0;

    if (flags.moveForward) {
        camera.moveForward(moveRate);
    }
    if (flags.moveBackward) {
        camera.moveBackward(moveRate);
    }
    if (flags.moveUp) {
        camera.moveUp(moveRate);
    }
    if (flags.moveDown) {
        camera.moveDown(moveRate);
    }
    if (flags.moveLeft) {
        camera.moveLeft(moveRate);
    }
    if (flags.moveRight) {
        camera.moveRight(moveRate);
    }
});
这里我们是把监听事件加载clock的onTick上的,这是一个以毫秒为单位的回调,完全可以保证我们的镜头移动的流畅

完整代码如下

//相机设置
var viewer = new Cesium.Viewer("cesiumContainer");
var scene = viewer.scene;
var canvas = viewer.canvas;
canvas.setAttribute('tabindex', '0'); // 需要把焦点放在画布上
canvas.onclick = function() {
    canvas.focus();
};
//这个椭球形就是地球了
var ellipsoid = viewer.scene.globe.ellipsoid;

// 禁止默认的事件
scene.screenSpaceCameraController.enableRotate = false;
scene.screenSpaceCameraController.enableTranslate = false;
scene.screenSpaceCameraController.enableZoom = false;
scene.screenSpaceCameraController.enableTilt = false;
scene.screenSpaceCameraController.enableLook = false;

//存储鼠标位置的变量
var startMousePosition;
var mousePosition;

var flags = {
    //记录是否在查看地图,也就是记录是否点击了鼠标或键盘
    looking : false,
    //记录键盘的前后上下左右
    moveForward : false,
    moveBackward : false,
    moveUp : false,
    moveDown : false,
    moveLeft : false,
    moveRight : false
};

//监听用户的输入
var handler = new Cesium.ScreenSpaceEventHandler(canvas);
//当鼠标左键按下时执行(拿到鼠标按下时的位置)
handler.setInputAction(function(movement) {
    flags.looking = true;
    mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
//当鼠标移动时执行(拿到鼠标抬起时的位置)
handler.setInputAction(function(movement) {
    mousePosition = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//当鼠标左键抬起时执行
handler.setInputAction(function(position) {
    flags.looking = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);

//判断键盘的输入
function getFlagForKeyCode(keyCode) {
    switch (keyCode) {
    case 'W'.charCodeAt(0):
        return 'moveUp';
    case 'S'.charCodeAt(0):
        return 'moveDown';
    case 'Q'.charCodeAt(0):
        return 'moveForward';
    case 'E'.charCodeAt(0):
        return 'moveBackward';
    case 'D'.charCodeAt(0):
        return 'moveRight';
    case 'A'.charCodeAt(0):
        return 'moveLeft';
    default:
        return undefined;
    }
}
//获得键盘keydown事件
document.addEventListener('keydown', function(e) {
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = true;
    }
}, false);
//获得键盘keyup事件
document.addEventListener('keyup', function(e) {
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = false;
    }
}, false);

//更新相机
viewer.clock.onTick.addEventListener(function(clock) {
    console.log("dida");
    var camera = viewer.camera;
    //当按下鼠标左键时
    if (flags.looking) {
        var width = canvas.clientWidth;
        var height = canvas.clientHeight;

        // 鼠标滑动的距离的x或y/网页可见区域的宽或者高
        var x = (mousePosition.x - startMousePosition.x) / width;
        var y = -(mousePosition.y - startMousePosition.y) / height;
        //这就是决定相机移动速度的参数
        var lookFactor = 0.05;
        //相机移动
        camera.lookRight(x * lookFactor);
        camera.lookUp(y * lookFactor);
    }

    // 镜头移动的速度基于镜头离地球的高度
    var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
    var moveRate = cameraHeight / 100.0;

    if (flags.moveForward) {
        camera.moveForward(moveRate);
    }
    if (flags.moveBackward) {
        camera.moveBackward(moveRate);
    }
    if (flags.moveUp) {
        camera.moveUp(moveRate);
    }
    if (flags.moveDown) {
        camera.moveDown(moveRate);
    }
    if (flags.moveLeft) {
        camera.moveLeft(moveRate);
    }
    if (flags.moveRight) {
        camera.moveRight(moveRate);
    }
});
参考资料:官网教程官方API
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值