Skip to content

useScenePick

A reactive wrapper for Cesium.Scene.pick: it picks the first object in the scene at the given screen coordinates and exposes the result as a reactive ref. Pass the coordinates (a ref or getter) and it throttles and picks automatically, caching results for identical conditions; use it for hover highlighting or feeding the result into reactive state such as a floating info panel.

Usage

vue
<script setup lang="ts">
import * as Cesium from 'cesium';
import { useEntity, useScenePick, useScreenSpaceEventHandler } from 'vesium';
import { computed, shallowRef } from 'vue';

const cursorPosition = shallowRef<Cesium.Cartesian2>();

// track mouse move to get screen position
useScreenSpaceEventHandler(Cesium.ScreenSpaceEventType.MOUSE_MOVE, (movement: { endPosition: Cesium.Cartesian2 }) => {
  cursorPosition.value = movement.endPosition.clone();
});

// use scene pick to pick entity at cursor
const pick = useScenePick(cursorPosition, {
  width: 3,
  height: 3,
});

// show pick result
const pickInfo = computed(() => {
  if (!pick.value)
    return 'No object picked';
  if (pick.value.id instanceof Cesium.Entity) {
    return `Picked Entity: ${pick.value.id.name || 'unnamed'}`;
  }
  if (pick.value.primitive) {
    return `Picked Primitive: ${(pick.value.primitive as any).id?.name || 'unnamed'}`;
  }
  return `Picked: ${JSON.stringify(pick.value)}`;
});

// add some entities for picking
const _entity1 = useEntity(new Cesium.Entity({
  name: 'Red Box',
  position: Cesium.Cartesian3.fromDegrees(120, 30, 100),
  box: {
    dimensions: new Cesium.Cartesian3(1000, 1000, 1000),
    material: Cesium.Color.RED,
  },
}));

const _entity2 = useEntity(new Cesium.Entity({
  name: 'Blue Box',
  position: Cesium.Cartesian3.fromDegrees(120.01, 30, 100),
  box: {
    dimensions: new Cesium.Cartesian3(1000, 1000, 1000),
    material: Cesium.Color.BLUE,
  },
}));
</script>

<template>
  <div style="position: fixed; top: 10px; left: 10px; padding: 8px; color: white; background: rgb(0 0 0 / 70%); border-radius: 4px;">
    {{ pickInfo }}
  </div>
</template>
ts
import * as Cesium from 'cesium';
import { useScenePick, useScreenSpaceEventHandler } from 'vesium';
import { shallowRef } from 'vue';

const cursorPosition = shallowRef<Cesium.Cartesian2>();
useScreenSpaceEventHandler(Cesium.ScreenSpaceEventType.MOUSE_MOVE, (m) => {
  cursorPosition.value = m.endPosition.clone();
});
const pick = useScenePick(cursorPosition);
if (pick.value?.id instanceof Cesium.Entity) {
  console.log(pick.value.id.name);
}

Options

  • isActive - Whether picking is active, defaults to true; when false the result is reset to undefined. Supports a ref/getter for dynamic control.
  • throttled - The throttled sampling interval (ms) for coordinate changes, defaults to 8.
  • width / height - The width and height of the pick rectangle, defaults to 3, forwarded to scene.pick and part of the result cache key.

Return Value

  • Returns Readonly<ShallowRef<ScenePickResult | undefined>>: the pick result (fields such as id and primitive match scene.pick, full list in the type definitions); undefined when nothing is picked.

Notes

  • Coordinate changes are throttled (8ms by default), so high-frequency mouse movement does not trigger scene.pick on every event.
  • When the viewer is missing, the position is empty, or isActive is false, the result is reset to undefined.
  • If scene.pick throws, an error is logged and the result is set to undefined.

Type Definitions

typescript
import type { ScenePickResult } from '@vesium/shared';
import type { Cartesian2 } from 'cesium';
import type { MaybeRefOrGetter, ShallowRef } from 'vue';
export interface UseScenePickOptions {
    /**
     * Whether to active the event listener.
     * @default true
     */
    isActive?: MaybeRefOrGetter<boolean>;
    /**
     * Throttled sampling (ms)
     * @default 8
     */
    throttled?: number;
    /**
     * The width of the pick rectangle.
     * @default 3
     */
    width?: MaybeRefOrGetter<number | undefined>;
    /**
     * The height of the pick rectangle.
     * @default 3
     */
    height?: MaybeRefOrGetter<number | undefined>;
}
/**
 * Uses the `scene.pick` function in Cesium's Scene object to perform screen point picking,
 * return a computed property containing the pick result, or undefined if no object is picked.
 *
 * @param windowPosition The screen coordinates of the pick point.
 */
export declare function useScenePick(windowPosition: MaybeRefOrGetter<Cartesian2 | undefined>, options?: UseScenePickOptions): Readonly<ShallowRef<ScenePickResult | undefined>>;