const viewer = new Cesium.Viewer(‘cesiumContainer’, {
shouldAnimate: true,
imageryProvider: new window.Cesium.SingleTileImageryProvider({
url: Cesium.buildModuleUrl(‘Assets/Textures/earth_color_low_4096.jpg’),
}),
});
// Function to convert pixelOffset to world position
function changeToThree(position, viewer) {
if (!position) return [];
return viewer.scene.globe.pick(viewer.camera.getPickRay(position), viewer.scene);
}
var entity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
billboard: {
image: './target/bu/410.png',
// width: 32,
// height: 32,
},
label: {
text: 'Drag me',
font: '14pt sans-serif',
fillColor: Cesium.Color.WHITE,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// pixelOffset: new Cesium.Cartesian2(0, -32), // Label initially above the billboard
pixelOffset: new Cesium.Cartesian2(0, 32)
},
polyline: {
// positions: [Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)], // Initial positions (same as billboard)
positions: new Cesium.CallbackProperty(function (time, result) {
var originPositionPixel = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, entity.position.getValue()) || new Cesium.Cartesian2(0, 0);
let pixelOffset = entity.label.pixelOffset.getValue();
let labelPositionPixel = Cesium.Cartesian2.add(originPositionPixel, pixelOffset, new Cesium.Cartesian2(0, 0));
let labelPosition = changeToThree(labelPositionPixel, viewer) || entity.position.getValue();
let entityPosition = entity.position.getValue();
return [entityPosition, labelPosition];
// var labelWorldPosition = getLabelWorldPosition(entity);
// return [entity.position.getValue(Cesium.JulianDate.now()), labelWorldPosition]
}, false),
width: 2,
material: Cesium.Color.RED,
},
});
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
var isDragging = false;
var pickedLabel;
var initialOffset;
var startPosition;
var scene = viewer.scene;
// Function to convert pixelOffset to world position (approximated)
function getLabelWorldPosition(labelEntity) {
var cartographicPosition = Cesium.Cartographic.fromCartesian(entity.position.getValue(Cesium.JulianDate.now()), viewer.scene.globe.ellipsoid);
var screenPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, entity.position.getValue(Cesium.JulianDate.now()));
var labelScreenPosition = new Cesium.Cartesian2(screenPosition.x + labelEntity.label.pixelOffset.getValue().x, screenPosition.y + labelEntity.label.pixelOffset.getValue().y);
// var newPosition = viewer.camera.pickEllipsoid(labelScreenPosition, viewer.scene.globe.ellipsoid) || entity.position.getValue(Cesium.JulianDate.now());
// If the new world position is undefined (off the globe), return undefined
var newPosition = viewer.camera.pickEllipsoid(labelScreenPosition, viewer.scene.globe.ellipsoid);
return newPosition;
}
// Mouse down event to pick the label and start dragging
handler.setInputAction(function (movement) {
var pickedObject = viewer.scene.pick(movement.position);
if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id.label)) {
isDragging = true;
pickedLabel = pickedObject.id;
initialOffset = pickedLabel.label.pixelOffset.getValue(); // Store initial pixelOffset
startPosition = movement.position; // Store the start position of the mouse
viewer.scene.screenSpaceCameraController.enableRotate = false; // Disable camera control while dragging
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
// Mouse move event to drag the label and update the polyline
handler.setInputAction(function (movement) {
if (isDragging) {
var deltaX = movement.endPosition.x - startPosition.x;
var deltaY = movement.endPosition.y - startPosition.y;
// Update the pixelOffset based on mouse movement
pickedLabel.label.pixelOffset = new Cesium.Cartesian2(
initialOffset.x + deltaX, // Adjust x offset
initialOffset.y + deltaY // Adjust y offset
);
// Calculate the new world position of the label based on its pixelOffset
// Check if the label is now off the globe
var labelWorldPosition = getLabelWorldPosition(pickedLabel);
if (!labelWorldPosition) {
// Reset the pixelOffset if the label is off the globe
pickedLabel.label.pixelOffset = new Cesium.Cartesian2(0, 32);
}
// Update polyline positions to connect billboard and label
// pickedLabel.polyline.positions = [
// entity.position.getValue(Cesium.JulianDate.now()), // Billboard position
// labelWorldPosition, // Draggable label's new world position
// ];
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// Mouse up event to stop dragging
handler.setInputAction(function () {
if (isDragging) {
isDragging = false;
pickedLabel = undefined;
viewer.scene.screenSpaceCameraController.enableRotate = true; // Re-enable camera control
}
}, Cesium.ScreenSpaceEventType.LEFT_UP);