I've been developing a webapp using Cesium and have hit a roadblock with respect to user interaction. After digging through the API and this forum for the last couple of weeks, I'm running low on ideas and decided to post on your forum.
I have a globe that has several objects displayed as Billboards. I'm trying to implement the following actions:
- Click and drag to move a billboard
- Double click on objects or a geographic location to re-centre the camera
A minor use case would be to click repeatedly to iterate through a list co-located objects to choose a specific object of interest. It's pretty easy behaviour, but adds some complexity to deciding which object to perform the previous actions on.
The Double Click behaviour is relatively easy:
Listening to Screen_Space_Event_Type.LEFT_DOUBLE_CLICK, use the cursor position in Scene.pick(windowPosition) to get the object (if available) and use Camera.flyTo(options) to re-centre the camera. If the object isn't available, simply re-centre on the geographic position of the cursor.
The click and drag behaviour is proving difficult:
It is essentially a compound set of actions LEFT_DOWN, MOUSE_MOVE and LEFT_UP.
- On Screen_Space_Event_Type.LEFT_DOWN, I can use Scene.Pick() to test if an object is available, or use the selected object from the previous left click. If an object is selected on LEFT_DOWN, the camera can temporarily be disabled by setting ScreenSpaceCameraController.enableInputs to false.
- On Screen_Space_Event_Type.MOUSE_MOVE (while the mouse is down), it would be nice to have the object follow the cursor location and have the camera slowly rotate towards the cursor position. This behaviour isn't essential and can wait.
- On Screen_Space_Event_Type.LEFT_UP if the geographic position is valid, move the object to that position. Billboards can be repositioned using the position attribute.
The difficulty comes from the fact that MOUSE_MOVE is incredibly sensitive, and that a LEFT_CLICK action is composed of a LEFT_DOWN and LEFT_UP sequence, where on a click; any accidental move should be reverted. A LEFT_DOUBLE_CLICK event is encountered following the sequence "LEFT_DOWN=>LEFT_UP=>LEFT_CLICK=>LEFT_DOWN=>LEFT_UP=>LEFT_CLICK"
Any moves and track selection on a double click event should be reverted.
At the moment, I'm contemplating implementing a state machine or digging into Cesium's code to add the functionality I want.
Ideally, I'd listen to Camera_Event_Type.LEFT_DRAG. Does an event handler exist to listen to Camera events like this? Several other people have requested an example of using the CameraEventAggregator. I still need a way to listen for the events that are aggregated.
I apologize that I don't have code available; it's on a machine without Web Access. Essentially I have a Cesium Viewer with primitives that are added dynamically at run-time.
I'm using Cesium 1.2.