useScenePick
响应式封装 Cesium.Scene.pick:根据屏幕坐标拾取场景中的第一个对象,结果放入响应式引用。传入坐标(ref/getter)后自动节流执行拾取,相同条件下结果复用缓存;适合鼠标悬停高亮或把结果接入悬浮面板等响应式状态。
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);
}配置项
isActive- 是否激活拾取,默认true;为false时结果重置为undefined,支持 ref/getter 动态控制。throttled- 坐标变化的节流采样间隔(毫秒),默认8。width/height- 拾取矩形宽高,默认3,透传给scene.pick并参与结果缓存判断。
返回值
- 返回
Readonly<ShallowRef<ScenePickResult | undefined>>:拾取结果(id、primitive等字段对应scene.pick,完整字段见类型定义),未拾取到任何对象时为undefined。
注意事项
- 坐标变化先节流(默认 8ms),高频鼠标移动不会每次都触发
scene.pick。 - viewer 不存在、位置为空或
isActive为false时,结果重置为undefined。 scene.pick抛错时打印错误日志并将结果置为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>>;