Click and drag?

I see you can click on entity/cube drawn. Is it possible to click and drag a cube so it changes its position based on where you drag and release it with your mouse?

While there’s no out-of-the-box “mode” for doing this, it’s easy enough to do using existing functionality. Below is an example that you can post into Sandcastle and play with. It’s not perfect (I just wrote it 5 minutes ago) but it will hopefully get you started in the right direction.

var viewer = new Cesium.Viewer(‘cesiumContainer’, {infoBox : false, selectionIndicator : false});

var entity = viewer.entities.add({

name : ‘Red box with black outline’,

position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),

box : {

dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),

material : Cesium.Color.RED,

outline : true,

outlineColor : Cesium.Color.BLACK

}

});

var mousePosition = new Cesium.Cartesian2();

var mousePositionProperty = new Cesium.CallbackProperty(function(time, result){

var position = scene.camera.pickEllipsoid(mousePosition, undefined, result);

var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);

cartographic.height = 300000.0;

return Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic);

}, false);

var scene = viewer.scene;

var dragging = false;

var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);

handler.setInputAction(

function(click) {

var pickedObject = scene.pick(click.position);

if (Cesium.defined(pickedObject) && (pickedObject.id === entity)) {

dragging = true;

scene.screenSpaceCameraController.enableRotate = false;

Cesium.Cartesian2.clone(click.position, mousePosition);

entity.position = mousePositionProperty;

}

},

Cesium.ScreenSpaceEventType.LEFT_DOWN

);

handler.setInputAction(

function(movement) {

if (dragging) {

Cesium.Cartesian2.clone(movement.endPosition, mousePosition);

}

},

Cesium.ScreenSpaceEventType.MOUSE_MOVE

);

handler.setInputAction(

function(click) {

if(dragging) {

dragging = false;

scene.screenSpaceCameraController.enableRotate = true;

entity.position = scene.camera.pickEllipsoid(click.position);

}

},

Cesium.ScreenSpaceEventType.LEFT_UP

);

After dragging the box I noticed that as you move the camera the box appears to slide around, not keeping up with the terrain. I couldn’t figure out why though. Using console logs I can tell it’s not executing the handler functions anymore.

It would be neat if entities had a property called draggable.

The reason is because it sets the final position using click.position without re-adjusting the height like it does in the CallbackProperty, it would be an easy fix (in reality this was a quick and dirty example so I would abstract functionality into a class. There’s also issues with the code if you double click on the box (you can disable this easy enough though).

The problem with adding something like entity.draggable is that it’s way too high-level and needs to make too many assumptions about the nature of the data. For example, if the position isn’t a constant, non-time-dynamic value the dragging makes little sense. That’s not to say that object editing can’t be done in a generic opt-in sort of way. In the long term I’m sure we’ll have something, (and it may be a plug-in) but there are way to many other core things that need work first. There is the DrawHelper plug-in already, but I’ve never tried it: https://github.com/leforthomas/cesium-drawhelper

Ah, so that’s what’s causing it. Changing the last setInputAction to the following fixes it.
handler.setInputAction(
function(click) {
if(dragging) {
dragging = false;
scene.screenSpaceCameraController.enableRotate = true;
var mypos = scene.camera.pickEllipsoid(click.position);
var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(mypos);
cartographic.height = 300000.0;
var mypos = Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic);
entity.position = mypos;
}
},
Cesium.ScreenSpaceEventType.LEFT_UP
);

``

Perhaps someone could make a Cesium editor plugin sometime in the future, with the ability of not only dragging entire entities, but moving vertices around as well. That drawhelper app does this, but for now limited to very basic geometries. I wonder if it can output the resulting drawing to entity code.

Just wanted to add that I also need the ability to drag entire entities as well as moving the vertices.

Maybe the author of https://github.com/leforthomas/cesium-drawhelper might continue their work if there’s enough interest, it’s been 7 months since the last update to the project. Be sure to check out the live demo at http://pad.geocento.com/DrawHelper/

I actually found that a while ago and was planning to use it for as much as I can. That's a great idea though, I think I might contact the author and let him know there is interest in this so he's aware.

This is crazy late, but I've created my own set of shape creation tools to be used with the latest versions of Cesium.
Drawhelper project was a great reference but hasn't been updated in quite a long time.

I will post back once I have everything ready for sharing.
Its still a bit rough at the moment but works very similarly.

Chris,

I look forward to your follow-up. Drawing tools in Cesium would be extremely helpful for my project.

Sounds great, Chris! Keep us posted! We’re interested in what solutions you come up with.

Best,

  • Rachel

Hi,

Is it possible to improve the drag & drop solution allowing only moving the object in a certain axis? Or to rotate the object over itself?

Thanks in advance

Best regards

Hi,

Yep! Just modify the code to only set the movement in the axis you want. For rotation, you can check how far the mouse has moved from some original position, convert that distance into degrees of rotation and update the entity’s orientation accordingly. Shouldn’t been too hard.

Unfortunately, I don’t currently have the bandwidth to make you a code example, but I’ll come back to this thread if I get the chance later.

Best,

  • Rachel

Hi all, I am also trying to implement drag on x - y axis.
I have a box entity and I placed point entities on its circumference. By dragging each point I would like to resize and rotate the box.

Capture

To achieve the desired behavior I need the point to only move on the plane of the top face of the box.
has anyone achieved a similar behavior?

thank you all