useGraphicEvent
Unified click, hover, and drag event listeners plus mouse cursor styles for Cesium graphics (Entity, Primitive, DataSource, etc.): scene.pick happens internally and callbacks fire only when the target graphic is hit. Listeners live in a WeakMap and are released automatically when the graphic is garbage collected or the component unmounts — no need to worry about leaks.
Usage
vue
<script setup lang="ts">
import { canvasCoordToCartesian, toProperty } from '@vesium/shared';
import * as Cesium from 'cesium';
import { useEntity, useGraphicEvent, useViewer } from 'vesium';
import { watchEffect } from 'vue';
const viewer = useViewer();
watchEffect(() => {
viewer.value?.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(150, 12.5, 9000000),
});
});
const graphicEvent = useGraphicEvent();
// =========[CLICK]============
useEntity(() => {
const entity = new Cesium.Entity({
position: Cesium.Cartesian3.fromDegrees(140, 10),
point: { pixelSize: 15 },
label: {
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 20),
text: 'CLICK ME',
},
});
graphicEvent.add(
entity,
'LEFT_CLICK',
(_params) => {
const color = new Cesium.ConstantProperty(Cesium.Color.RED);
entity!.point!.color = color;
entity!.label!.fillColor = color;
entity!.label!.text = new Cesium.ConstantProperty('CLICKED');
},
);
return entity;
});
// =========[HOVER]============
useEntity(() => {
const entity = new Cesium.Entity({
position: Cesium.Cartesian3.fromDegrees(150, 10),
point: { pixelSize: 15 },
label: {
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 20),
text: 'HOVER ME',
},
});
graphicEvent.add(
entity,
'HOVER',
(params) => {
const color = params.hovering ? Cesium.Color.RED : undefined;
entity!.point!.color = toProperty(color);
entity!.label!.fillColor = toProperty(color);
entity!.label!.text = toProperty(params.hovering ? 'HOVERING' : 'HOVER ME');
},
);
return entity;
});
// =========[DRAG]============
useEntity(() => {
const entity = new Cesium.Entity({
position: Cesium.Cartesian3.fromDegrees(160, 10),
point: { pixelSize: 15 },
label: {
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 20),
text: 'DRAG ME',
},
});
graphicEvent.add(
entity,
'DRAG',
(params) => {
const color = params.dragging ? Cesium.Color.RED : undefined;
entity!.point!.color = toProperty(color);
entity!.label!.fillColor = toProperty(color);
entity!.label!.text = toProperty(params.dragging ? 'DRAGGING' : 'DRAG ME');
// lock camera
params.dragging && params.lockCamera();
// update position
const position = canvasCoordToCartesian(params.event.endPosition, viewer.value!.scene);
if (position) {
entity!.position = new Cesium.CallbackPositionProperty(() => position, false);
}
},
);
return entity;
});
</script>
<template>
<div />
</template>ts
import * as Cesium from 'cesium';
import { useEntity, useGraphicEvent } from 'vesium';
const graphicEvent = useGraphicEvent();
useEntity(() => {
const entity = new Cesium.Entity({
position: Cesium.Cartesian3.fromDegrees(140, 10),
point: { pixelSize: 15 }, // an entity with a graphic can be picked
});
graphicEvent.add(entity, 'LEFT_CLICK', ({ pick }) => {
console.log('clicked', pick.id);
});
graphicEvent.add(entity, 'HOVER', ({ hovering }) => {
entity.point!.color = new Cesium.ConstantProperty(hovering ? Cesium.Color.RED : Cesium.Color.WHITE);
});
return entity;
});Options (options of add)
cursor- The cursor style on hover, defaults to'pointer'; can be a string or a function(event: GraphicHoverEvent) => string | null | undefined.dragCursor- The cursor style while dragging, defaults to'crosshair'(only takes effect forDRAGevents, and only while dragging).
Return Value
add(graphic, type, listener, options?)- Registers a listener and returns a remove function; pass'global'asgraphicto fire when any graphic is hit;typeis'HOVER','DRAG', or a positioned event type such as'LEFT_CLICK'(full list in the type definitions).remove/clear- Remove / clear the listeners of the given graphic; pass'all'asclear'stypeto clear every listener on that graphic.- Event payloads: positioned events are
{ event, pick };HOVERaddshovering: boolean;DRAGaddsdragging: booleanandlockCamera().
Notes
graphiccan be any object pickable byscene.pick(Entity,Primitive,DataSource, etc.);'global'is stored under an internal symbol, so clean it up explicitly viaremove/clearor the remove function returned byadd. No need to worry about leaks: listeners in theWeakMapare released when the graphic is garbage collected, and the internal screen events stop on component unmount.
Type Definitions
typescript
import type { Nullable } from '@vesium/shared';
import type { Entity } from 'cesium';
import type { GraphicDragEvent } from './useDrag';
import type { GraphicHoverEvent } from './useHover';
import type { GraphicPositionedEvent, PositionedEventType } from './usePositioned';
export type CesiumGraphic = Entity | any;
export type GraphicEventType = PositionedEventType | 'HOVER' | 'DRAG';
export type GraphicEventListener<T extends GraphicEventType> = T extends 'DRAG' ? (event: GraphicDragEvent) => void : T extends 'HOVER' ? (event: GraphicHoverEvent) => void : (event: GraphicPositionedEvent) => void;
export type removeFn = () => void;
export interface AddGraphicEventOptions {
/**
* The cursor style to use when the mouse is over the graphic.
* @default 'pointer'
*/
cursor?: Nullable<string> | ((event: GraphicHoverEvent) => Nullable<string>);
/**
* The cursor style to use when the mouse is over the graphic during a drag operation.
* @default 'crosshair'
*/
dragCursor?: Nullable<string> | ((event: GraphicHoverEvent) => Nullable<string>);
}
export interface UseGraphicEventReturn {
/**
* Add a graphic event listener and return a function to remove it.
* @param graphic - The graphic object, 'global' indicates the global graphic object.
* @param type - The event type, 'all' indicates clearing all events.
* @param listener - The event listener function.
*/
add: <T extends GraphicEventType>(graphic: CesiumGraphic | 'global', type: T, listener: GraphicEventListener<T>, options?: AddGraphicEventOptions) => removeFn;
/**
* Remove a graphic event listener.
* @param graphic - The graphic object, 'global' indicates the global graphic object.
* @param type - The event type, 'all' indicates clearing all events.
* @param listener - The event listener function.
*/
remove: <T extends GraphicEventType>(graphic: CesiumGraphic | 'global', type: T, listener: GraphicEventListener<T>) => void;
/**
* Clear graphic event listeners.
* @param graphic - The graphic object.
* @param type - The event type, 'all' indicates clearing all events.
*/
clear: (graphic: CesiumGraphic | 'global', type: GraphicEventType | 'all') => void;
}
/**
* Handle graphic event listeners and cursor styles for Cesium graphics.
* You don't need to overly worry about memory leaks from the function, as it automatically cleans up internally.
*/
export declare function useGraphicEvent(): UseGraphicEventReturn;