Skip to content
Development
Skill

/cesiumjs-interaction

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

From plugin
cesiumjs-skills
17815 skills1 hook1 MCP
Install
$ npx -y skills add CesiumGS/cesiumjs-skills --skill cesiumjs-interaction --agent claude-code

How 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.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • 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, Scene.snap edge snapping (1.144), mouse and touch events. Use when handling user clicks on the globe, selecting entities or

SKILL.md

cesiumjs-interaction.SKILL.md
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."

CesiumJS Interaction & Picking

Version baseline: CesiumJS v1.144 (ES module imports, Ion token required).

ScreenSpaceEventHandler

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.

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"));
}

snap (experimental, 1.144+)

`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

Read more
Ships withcesiumjs-skills

Curated agent skills for CesiumJS development — 14 domain skills covering ~551 public symbols across the CesiumJS v1.143 API surface.

Get the whole plugin
Stats
178
Stars
21
Forks
Active
Maintenance
JavaScript
Language
Apache-2.0
License
5d ago
Last commit
5mo ago
Created

Repo: CesiumGS/cesiumjs-skills

Other skills on cesiumjs-skills.