/cesiumjs-interaction
CesiumJS interaction and picking - ScreenSpaceEventHandler, multi-key KeyboardEventModifier input actions, Scene.pick, Scene.drillPick, Scene.pickPosition, mouse and touch events. Use when handling user clicks on the globe, selecting entities or 3D Tiles features, registering
$ 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.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/cesiumjs-interaction
Context 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, mouse and touch events. Use when handling user clicks on the globe, selecting entities or 3D Tiles features, registering
SKILL.md
cesiumjs-interaction.SKILL.mdname: cesiumjs-interaction
description: "CesiumJS interaction and picking - ScreenSpaceEventHandler, multi-key KeyboardEventModifier input actions, Scene.pick, Scene.drillPick, Scene.pickPosition, 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, or building drag-based interactions."
CesiumJS Interaction & Picking
Version baseline: CesiumJS v1.143 (ES module imports, Ion token required).
ScreenSpaceEventHandler
Central class for mouse, touch, and pointer events on the Cesium canvas.
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 has a built-in handler at `viewer.screenSpaceEventHandler` -- use it to avoid creating a second handler for simple cases.
ScreenSpaceEventType Reference
| 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.
Scene Picking Methods
pick / pickAsync / drillPick / pickPosition
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`.
pickVoxel (experimental)
// Pick a voxel cell and read its properties
const voxelCell = viewer.scene.pickVoxel(event.position);
if (defined(voxelCell)) {
console.log(voxelCell.getProperty("temperature"));
}Picking Return Values
| Picked object | Return shape | Key properties | |---|---|---| | Entity | `{ primitive, id }` | `id` is the `Entity` instance | | Cesium3DTileFeature | `Cesium3DTileFeature` | `.getProperty(name)`, `.getPropertyIds()`, `.color` | | Billboard/Label (collection) | `{ primitive, id }` | `id` is the user-set id | | Primitive (geometry) | `{ primitive, id }` | `id` is the `GeometryInstance` id | | Globe surface | `undefined` | Use `camera.pickEllipsoid()` or `pickPosition()` |
Recipes
1. Entity Selection with Click
handler.setInputAction((event) => {
const picked = viewer.scene.pick(event.position);
if (defined(picked) && defined(picked.id)) {
viewer.selectedEntity = picked.id; // shows InfoBox
} else {
viewer.selectedEntity = undefined;
}
}, ScreenSpaceEventType.LEFT_CLICK);2. 3D Tiles Feature Picking and Property Inspection
import { Cesium3DTileFeature, Color } from "cesium";
handler.setInputAction((event) => {
const picked = viewer.scene.pick(event.position);
if (picked instanceof Cesium3DTileFeature) {
// Read properties
const ids = picked.getPropertyIds();
ids.forEach((id) => console.log(`${id}: ${picked.getProperty(id)}`));
picked.color = Color.YELLOW; // highlight
}
}, ScreenSpaceEventType.LEFT_CLICK);3. Terrain Position Picking (Lon/Lat from Click)
handler.setInputAction((event) => {
const cartesian = viewer.camera.pickEllipsoid(
event.position, viewer.scene.globe.ellipsoid);
if (defined(cartesiRead more
name: cesiumjs-interaction description: "CesiumJS interaction and picking - ScreenSpaceEventHandler, multi-key KeyboardEventModifier input actions, Scene.pick, Scene.drillPick, Scene.pickPosition, 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, or building drag-based interactions."
CesiumJS Interaction & Picking
Version baseline: CesiumJS v1.143 (ES module imports, Ion token required).
ScreenSpaceEventHandler
Central class for mouse, touch, and pointer events on the Cesium canvas.
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 has a built-in handler at `viewer.screenSpaceEventHandler` -- use it to avoid creating a second handler for simple cases.
ScreenSpaceEventType Reference
| 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.
Scene Picking Methods
pick / pickAsync / drillPick / pickPosition
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`.
pickVoxel (experimental)
// Pick a voxel cell and read its properties
const voxelCell = viewer.scene.pickVoxel(event.position);
if (defined(voxelCell)) {
console.log(voxelCell.getProperty("temperature"));
}Picking Return Values
| Picked object | Return shape | Key properties | |---|---|---| | Entity | `{ primitive, id }` | `id` is the `Entity` instance | | Cesium3DTileFeature | `Cesium3DTileFeature` | `.getProperty(name)`, `.getPropertyIds()`, `.color` | | Billboard/Label (collection) | `{ primitive, id }` | `id` is the user-set id | | Primitive (geometry) | `{ primitive, id }` | `id` is the `GeometryInstance` id | | Globe surface | `undefined` | Use `camera.pickEllipsoid()` or `pickPosition()` |
Recipes
1. Entity Selection with Click
handler.setInputAction((event) => {
const picked = viewer.scene.pick(event.position);
if (defined(picked) && defined(picked.id)) {
viewer.selectedEntity = picked.id; // shows InfoBox
} else {
viewer.selectedEntity = undefined;
}
}, ScreenSpaceEventType.LEFT_CLICK);2. 3D Tiles Feature Picking and Property Inspection
import { Cesium3DTileFeature, Color } from "cesium";
handler.setInputAction((event) => {
const picked = viewer.scene.pick(event.position);
if (picked instanceof Cesium3DTileFeature) {
// Read properties
const ids = picked.getPropertyIds();
ids.forEach((id) => console.log(`${id}: ${picked.getProperty(id)}`));
picked.color = Color.YELLOW; // highlight
}
}, ScreenSpaceEventType.LEFT_CLICK);3. Terrain Position Picking (Lon/Lat from Click)
handler.setInputAction((event) => {
const cartesian = viewer.camera.pickEllipsoid(
event.position, viewer.scene.globe.ellipsoid);
if (defined(cartesiShowing the first part of this file.
Curated agent skills for CesiumJS development — 14 domain skills covering ~551 public symbols across the CesiumJS v1.143 API surface.
Repo: CesiumGS/cesiumjs-skills
Other skills on cesiumjs-skills.
- /cesiumjs-3d-tiles
CesiumJS 3D Tiles - Cesium3DTileset, compressed and CAD-style glTF content, MVTDataProvider, styling, metadata, feature picking, voxels, point clouds, I3S, Gaussian splats, clipping. Use when loading 3D Tiles or Mapbox Vector Tiles, rendering KHR meshopt/CAD content, styling or
Open skill - /cesiumjs-camera
CesiumJS camera control - Camera, flyTo, lookAt, setView, ScreenSpaceCameraController, CameraEventAggregator, flight animation. Use when positioning the camera, creating flyTo animations, constraining user navigation, tracking entities, or converting between screen and world
Open skill - /cesiumjs-core-utilities
CesiumJS core utilities and networking - Resource, Color, Event, Request, RequestScheduler, error handling, helper functions, feature detection. Use when fetching remote data, managing HTTP requests, working with colors, handling events, debugging errors, or using utility
Open skill - /cesiumjs-custom-shader
CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czm_modelMaterial. Use when reading EXT_mesh_features or EXT_structural_metadata property textures/tables, vertex displacement, or shading VoxelPrimitive.
Open skill - /cesiumjs-entities
CesiumJS entities and data sources - Entity, EntityCollection, DataSource, GeoJsonDataSource, KmlDataSource, CzmlDataSource, Graphics types, PathGraphics, PathMode, Visualizers. Use when adding points, labels, models, polygons, polylines, or time-segmented paths, loading
Open skill - /cesiumjs-imagery
CesiumJS imagery layers - ImageryProvider, ImageryLayer, ImageryLayerCollection, WMS, WMTS, Bing, OpenStreetMap, ArcGIS, Mapbox, tile discard policies. Use when adding or swapping base map layers, configuring imagery providers, layering multiple map sources, or creating
Open skill

