cesiumjs-3d-tiles
CesiumJS 3D Tiles - Cesium3DTileset, compressed and CAD-style glTF content, MVTDataProvider, UrlTemplate3DTilesDataProvider, styling, metadata, feature…
CesiumJS interaction and picking - ScreenSpaceEventHandler, multi-key KeyboardEventModifier input actions, Scene.pick, Scene.drillPick, Scene.pickPosition, Scene.snap edge snapping (1.144), mouse and touch events. Use when handling user clicks on the globe, selecting entities or
$ npx -y skills add CesiumGS/cesiumjs-skills --skill cesiumjs-interaction --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/cesiumjs-interactionContext preview
The summary Claude sees to decide when to auto-load this skill.
CesiumJS interaction and picking - ScreenSpaceEventHandler, multi-key KeyboardEventModifier input actions, Scene.pick, Scene.drillPick, Scene.pickPosition, Scene.snap edge snapping (1.144), mouse and touch events. Use when handling user clicks on the globe, selecting entities or
name: cesiumjs-interaction description: "CesiumJS interaction and picking - ScreenSpaceEventHandler, multi-key KeyboardEventModifier input actions, Scene.pick, Scene.drillPick, Scene.pickPosition, Scene.snap edge snapping (1.144), mouse and touch events. Use when handling user clicks on the globe, selecting entities or 3D Tiles features, registering modifier-key shortcuts, implementing hover effects, snapping to model edges for measurement, or building drag-based interactions."
Version baseline: CesiumJS v1.144 (ES module imports, Ion token required).
Central class for mouse, touch, and pointer events on the Cesium canvas. **Always construct a new `ScreenSpaceEventHandler` bound to `viewer.scene.canvas` for interaction logic** -- it isolates your listeners from Cesium's default camera/selection handlers and is the idiomatic pattern shown across all recipes below.
import { ScreenSpaceEventHandler, ScreenSpaceEventType,
KeyboardEventModifier, defined } from "cesium";
let handler = new ScreenSpaceEventHandler(viewer.scene.canvas);
// Register a click handler
handler.setInputAction((event) => {
console.log("Clicked at", event.position.x, event.position.y);
}, ScreenSpaceEventType.LEFT_CLICK);
// With keyboard modifier (Shift+Click)
handler.setInputAction((event) => {
console.log("Shift+Click at", event.position);
}, ScreenSpaceEventType.LEFT_CLICK, KeyboardEventModifier.SHIFT);
// With multiple modifiers (Ctrl+Shift+Click, 1.142+)
handler.setInputAction((event) => {
console.log("Ctrl+Shift+Click at", event.position);
}, ScreenSpaceEventType.LEFT_CLICK, [
KeyboardEventModifier.CTRL,
KeyboardEventModifier.SHIFT,
]);
// Query or remove actions
const clickAction = handler.getInputAction(ScreenSpaceEventType.LEFT_CLICK);
const ctrlShiftClickAction = handler.getInputAction(ScreenSpaceEventType.LEFT_CLICK, [
KeyboardEventModifier.SHIFT,
KeyboardEventModifier.CTRL, // order does not matter
]);
if (defined(clickAction) && defined(ctrlShiftClickAction)) {
console.log("Click handlers registered");
}
handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK, [
KeyboardEventModifier.CTRL,
KeyboardEventModifier.SHIFT,
]);
// Always destroy when done to avoid memory leaks
handler = handler && handler.destroy();The Viewer also exposes a built-in handler at `viewer.screenSpaceEventHandler` which drives default behavior (entity selection, double-click tracking). You *can* attach to it, but for any non-trivial interaction prefer constructing your own `new ScreenSpaceEventHandler(viewer.scene.canvas)` so your handlers are independently disposable and do not collide with Cesium defaults.
| Event | Callback shape | Notes | |---|---|---| | `LEFT_DOWN` / `LEFT_UP` / `LEFT_CLICK` | `({ position })` | Cartesian2 screen coords | | `LEFT_DOUBLE_CLICK` | `({ position })` | Left only | | `RIGHT_DOWN` / `RIGHT_UP` / `RIGHT_CLICK` | `({ position })` | | | `MIDDLE_DOWN` / `MIDDLE_UP` / `MIDDLE_CLICK` | `({ position })` | | | `MOUSE_MOVE` | `({ startPosition, endPosition })` | Fires on every pointer move | | `WHEEL` | `(delta)` | Positive = scroll up | | `PINCH_START` | `({ position1, position2 })` | Two-finger touch begins | | `PINCH_END` | `()` | Two-finger touch ends | | `PINCH_MOVE` | `({ distance, angleAndHeight })` | Two-finger move |
`KeyboardEventModifier`: `SHIFT`, `CTRL`, `ALT` -- optional third argument to `setInputAction`, `getInputAction`, and `removeInputAction`. In 1.142+, pass a single modifier or an array of modifiers. Modifier arrays are order-independent but exact: a handler registered for `[CTRL, SHIFT]` does not fire when `ALT` is also held.
import { Cartographic, Math as CesiumMath, defined } from "cesium";
// pick -- synchronous, returns top-most object or undefined
const picked = viewer.scene.pick(event.position);
// pickAsync -- non-blocking (WebGL2, v1.136+), falls back to sync on WebGL1
const picked2 = await viewer.scene.pickAsync(movement.endPosition);
// drillPick -- all objects at position, front-to-back; use limit to cap cost
const allPicked = viewer.scene.drillPick(event.position, 5);
// pickPosition -- world Cartesian3 from depth buffer
if (viewer.scene.pickPositionSupported) {
const cartesian = viewer.scene.pickPosition(event.position);
if (defined(cartesian)) {
const c = Cartographic.fromCartesian(cartesian);
console.log(CesiumMath.toDegrees(c.longitude), CesiumMath.toDegrees(c.latitude), c.height);
}
}Set `scene.pickTranslucentDepth = true` to include translucent primitives in `pickPosition`.
// Pick a voxel cell and read its properties
const voxelCell = viewer.scene.pickVoxel(event.position);
if (defined(voxelCell)) {
console.log(voxelCell.getProperty("temperature"));
}`scene.snap` searches a screen-space region around a window position and returns the best snap target, preferring model edges (from CAD-style `EXT_mesh_primitive_edge_visibility` data) over surfaces; among hits of the same kind, the one nearest the cursor wins. Use it for measurement and inspection tools that should latch onto edges instead of raw cursor hits.
import { defined } from "cesium";
// Search a 25x25 px region centered on the cursor
const result = viewer.scene.snap(movement.endPosition, { width: 25 });
if (defined(result)) {
// SceneSnapResult: { object, position, screenPosition, isEdge }
console.log(result.isEdge ? "edge" : "surface", result.position);
}Only primitives rendered through the Model pipeline (3D Tiles and glTF models) are snappable. Snapping requires WebGL2 with float color attachments (`EXT_color_buffer_float`); when that is unsupported, or the region contains no snappable geometry, `snap` retur
Curated agent skills for CesiumJS development — 14 domain skills covering ~551 public symbols across the CesiumJS v1.143 API surface.
Repo: CesiumGS/cesiumjs-skills
CesiumJS 3D Tiles - Cesium3DTileset, compressed and CAD-style glTF content, MVTDataProvider, UrlTemplate3DTilesDataProvider, styling, metadata, feature…
CesiumJS camera control - Camera, flyTo, lookAt, setView, ScreenSpaceCameraController, composable Controller camera controllers (1.144), CameraEventAggregator,…
CesiumJS core utilities and networking - Resource, Color, Event, Request, RequestScheduler, error handling, helper functions, feature detection. Use when…
CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czm_modelMaterial. Use when reading…
CesiumJS entities and data sources - Entity, EntityCollection, DataSource, GeoJsonDataSource, KmlDataSource, CzmlDataSource, Graphics types, PathGraphics,…
CesiumJS imagery layers - ImageryProvider, ImageryLayer, ImageryLayerCollection, WMS, WMTS, Bing, OpenStreetMap, ArcGIS, Mapbox, tile discard policies. Use…