Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/javascript
CesiumJS中的Camera控制場景的視圖。有不少方法能夠操做Camera,如旋轉(rotate)、縮放(zoom)、平移(pan)和飛到目的地(flyTo)。CesiumJS有鼠標和觸摸事件用來處理與Camrea的交互,還有API來以編程方式操做攝像機。瞭解如何使用Camera API和自定義相機控制(Camera controls)。html
打開Sandcastle中的Hello World樣例用來體驗默認的相機控制。默認操做方式以下:java
鼠標操做 | 3D | 2D | Columbus視角 |
---|---|---|---|
Left click + drag | Rotate around the globe | Translate over the map | Translate over the map |
Right click + drag | Zoom in and out | Zoom in and out | Zoom in and out |
Middle wheel scrolling | Zoom in and out | Zoom in and out | Zoom in and out |
Middle click + drag | Tilt the globe | No action | Tilt the map |
鼠標操做 | 3D | 2D | Columbus視角 |
---|---|---|---|
左鍵 + 拖拽 | 旋轉地球 | 在地圖上移動 | 在地圖上移動 |
右鍵 + 拖拽 | 縮放 | 縮放 | 縮放 |
中鍵滾輪 | 縮放 | 縮放 | 縮放 |
中鍵 + 拖拽 | 傾斜地球 | 無操做 | 傾斜地球 |
使用setView函數設置Camera的位置和方向。destination能夠是Cartesian3或Rectangle,orientation能夠是heading/pitch/roll或direction/up。航向角、俯仰角和橫滾角以弧度定義。航向角是從正角度向東增長的局部北向旋轉。俯仰角是指從局部的東北平面開始的旋轉。正俯仰角在平面上方。負俯仰角在平面如下。很滾叫是圍繞局部東軸應用的第一個旋轉。編程
camera.setView({ destination : new Cesium.Cartesian3(x, y, z), orientation: { heading : headingAngle, pitch : pitchAngle, roll : rollAngle } });
viewer.camera.setView({ destination : Cesium.Rectangle.fromDegrees(west, south, east, north), orientation: { heading : headingAngle, pitch : pitchAngle, roll : rollAngle } });
上述的全部參數都是可選的。若是未指定,參數值將被設爲默認值用戶當前Camera的位置和方向。canvas
建立咱們本身的事件控制,根據鼠標的朝向用於控制Camera的朝向,鍵盤的按鍵控制Camera向前、向左、向右、向上,以及向下。首先從禁用默認事件操做開始。在(javascript var viewe=...
)以後添加下列代碼:ide
var scene = viewer.scene; var canvas = viewer.canvas; canvas.setAttribute('tabindex', '0'); // needed to put focus on the canvas canvas.onclick = function() { canvas.focus(); }; var ellipsoid = viewer.scene.globe.ellipsoid; // disable the default event handlers scene.screenSpaceCameraController.enableRotate = false; scene.screenSpaceCameraController.enableTranslate = false; scene.screenSpaceCameraController.enableZoom = false; scene.screenSpaceCameraController.enableTilt = false; scene.screenSpaceCameraController.enableLook = false;
建立變量記錄當前鼠標位置,而後標記並跟隨Camera移動軌跡:函數
var startMousePosition; var mousePosition; var flags = { looking : false, moveForward : false, moveBackward : false, moveUp : false, moveDown : false, moveLeft : false, moveRight : false };
添加一個事件控制用戶設置標記,當鼠標左鍵被點擊的時候,用於記錄當前鼠標的位置:ui
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);
建立鍵盤事件控制用戶切換Camera移動標記。咱們爲下列按鍵和行爲設置了標記:idea
function getFlagForKeyCode(keyCode) { switch (keyCode) { case 'W'.charCodeAt(0): return 'moveForward'; case 'S'.charCodeAt(0): return 'moveBackward'; case 'Q'.charCodeAt(0): return 'moveUp'; case 'E'.charCodeAt(0): return 'moveDown'; case 'D'.charCodeAt(0): return 'moveRight'; case 'A'.charCodeAt(0): return 'moveLeft'; default: return undefined; } } document.addEventListener('keydown', function(e) { var flagName = getFlagForKeyCode(e.keyCode); if (typeof flagName !== 'undefined') { flags[flagName] = true; } }, false); document.addEventListener('keyup', function(e) { var flagName = getFlagForKeyCode(e.keyCode); if (typeof flagName !== 'undefined') { flags[flagName] = false; } }, false);
如今當標記代表事件發生爲true是,咱們更新(update)camera。咱們新增**onTick的監聽事件在clock中:spa
viewer.clock.onTick.addEventListener(function(clock) { var camera = viewer.camera; });
接下來,咱們讓Camera指向鼠標指向的方向。在變量聲明以後添加下列代碼到事件監聽函數:
if (flags.looking) { var width = canvas.clientWidth; var height = canvas.clientHeight; // Coordinate (0.0, 0.0) will be where the mouse was clicked. 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); }
lookRight和lookUp只須要一個角度參數用於表示旋轉的角度。咱們將鼠標座標轉換爲範圍(-1.0,1.0),座標(0.0,0.0)位於畫布的中心。鼠標距中心的距離決定了旋轉的速度。靠近中心的位置移動Camera的速度較慢,而遠離中心的位置移動Camera的速度較快。
最後,添加代碼用於移動Camera的位置。而後添加下列代碼到事件響應函數:
// Change movement speed based on the distance of the camera to the surface of the ellipsoid. 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); }
moveForward、moveBackward、moveUp、moveDown、moveLeft和moveRight方法只須要一個距離參數(米)用於移動Camera的距離。當每個按鍵被按下時,Camera就會在球體表面移動固定的距離。Camera離地面越近,移動的速度就越慢。
完整的代碼以下:
var viewer = new Cesium.Viewer('cesiumContainer'); var scene = viewer.scene; var canvas = viewer.canvas; canvas.setAttribute('tabindex', '0'); // needed to put focus on the canvas canvas.onclick = function() { canvas.focus(); }; var ellipsoid = viewer.scene.globe.ellipsoid; // disable the default event handlers 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 'moveForward'; case 'S'.charCodeAt(0): return 'moveBackward'; case 'Q'.charCodeAt(0): return 'moveUp'; case 'E'.charCodeAt(0): return 'moveDown'; case 'D'.charCodeAt(0): return 'moveRight'; case 'A'.charCodeAt(0): return 'moveLeft'; default: return undefined; } } document.addEventListener('keydown', function(e) { var flagName = getFlagForKeyCode(e.keyCode); if (typeof flagName !== 'undefined') { flags[flagName] = true; } }, false); document.addEventListener('keyup', function(e) { var flagName = getFlagForKeyCode(e.keyCode); if (typeof flagName !== 'undefined') { flags[flagName] = false; } }, false); viewer.clock.onTick.addEventListener(function(clock) { var camera = viewer.camera; if (flags.looking) { var width = canvas.clientWidth; var height = canvas.clientHeight; // Coordinate (0.0, 0.0) will be where the mouse was clicked. 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); } // Change movement speed based on the distance of the camera to the surface of the ellipsoid. 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); } });
##Camera Camera表示Camera當前位置、方向、參考幀和視圖截錐的狀態。上面的Camera向量在每幀中都是正交的。 move**和zoom**函數平移Camera的位置按照它的方向或指定的方向矢量。方向保持固定不變。
look**和twist**函數旋轉Camera的方向好比向上、或向右矢量。位置保持固定不變。
*rotate**函數玄幻位置和方向基於給定矢量。
函數設置Camera給定範圍或位置和目標的Camera位置和方向。例如:
var west = Cesium.Math.toRadians(-77.0); var south = Cesium.Math.toRadians(38.0); var east = Cesium.Math.toRadians(-72.0); var north = Cesium.Math.toRadians(42.0); var extent = new Cesium.Extent(west, south, east, north); camera.viewExtent(extent, Cesium.Ellipsoid.WGS84);
建立變量ray,經過像素拾取Camera的位置。該方法可用於拾取,例如:
// find intersection of the pixel picked and an ellipsoid var ray = camera.getPickRay(mousePosition); var intersection = Cesium.IntersectionTests.rayEllipsoid(ray, Cesium.Ellipsoid.WGS84);
ScreenSpaceCameraController將用戶輸入(如鼠標和觸摸)從窗口座標轉換爲Camera運動。它包含用於啓用和禁用不一樣類型輸入、修改慣性量以及最小和最大縮放距離的屬性。
可在Sandcastle中查看camera樣例代碼:
API文檔:
Cesium中文網交流QQ羣:807482793 Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/