Skip to content

useCameraState ​

Reactive access to the Camera state (position, directions, heading/pitch/roll, level, and more). Reading viewer.camera.position directly does not trigger Vue's reactivity — the camera is driven by Cesium's internal render loop; this hook listens to camera events (default changed), throttles updates (default 8ms), and syncs the state into reactive data that follows animations, making it suitable for binding to UI (e.g. a coordinates panel) or driving other logic.

Usage ​

vue
<script setup lang="ts">
import { useCameraState } from 'vesium';

const {
  position,
  direction,
  up,
  right,
  positionCartographic,
  positionWC,
  directionWC,
  upWC,
  rightWC,
  viewRectangle,
  heading,
  pitch,
  roll,
  level,
} = useCameraState();

function fmtVec(v: { x: number; y: number; z: number } | undefined): string {
  return v ? `${v.x.toFixed(1)}, ${v.y.toFixed(1)}, ${v.z.toFixed(1)}` : '--';
}
</script>

<template>
  <div class="text-12px p-10px bg-[var(--vp-c-bg)] flex flex-col gap-y-4px h-full max-w-320px overflow-auto">
    <span data-testid="heading">heading: {{ heading?.toFixed(3) }}</span>
    <span data-testid="pitch">pitch: {{ pitch?.toFixed(3) }}</span>
    <span data-testid="roll">roll: {{ roll?.toFixed(3) }}</span>
    <span data-testid="level">level: {{ level }}</span>
    <span data-testid="pos-lon">lon: {{ positionCartographic ? (positionCartographic.longitude * 180 / Math.PI).toFixed(3) : '--' }}</span>
    <span data-testid="pos-lat">lat: {{ positionCartographic ? (positionCartographic.latitude * 180 / Math.PI).toFixed(3) : '--' }}</span>
    <span data-testid="pos-height">height: {{ positionCartographic?.height?.toFixed(1) }}</span>
    <span data-testid="position">position: {{ fmtVec(position) }}</span>
    <span data-testid="position-wc">positionWC: {{ fmtVec(positionWC) }}</span>
    <span data-testid="direction">direction: {{ fmtVec(direction) }}</span>
    <span data-testid="direction-wc">directionWC: {{ fmtVec(directionWC) }}</span>
    <span data-testid="up">up: {{ fmtVec(up) }}</span>
    <span data-testid="up-wc">upWC: {{ fmtVec(upWC) }}</span>
    <span data-testid="right">right: {{ fmtVec(right) }}</span>
    <span data-testid="right-wc">rightWC: {{ fmtVec(rightWC) }}</span>
    <pre data-testid="cartographic-json" class="text-11px whitespace-pre-wrap">{{ JSON.stringify({ position: positionCartographic, viewRectangle }, null, 2) }}</pre>
  </div>
</template>
ts
import { useCameraState } from 'vesium';

const { position, heading, pitch, roll, level } = useCameraState();

Options ​

  • camera - The camera to watch, default useViewer().value.scene.camera.
  • event - The event to watch: changed | moveStart | moveEnd, default changed.
  • delay - Throttled delay (ms), default 8.

Return Value ​

  • position - The camera position (world coordinates, cloned).
  • heading / pitch / roll - The camera heading / pitch / roll (radians).
  • level - The camera level (estimated from height).
  • Other fields (direction, positionCartographic, viewRectangle, etc.) are defined in the type definitions below.

Notes ​

  • The default camera comes from useViewer(), so createViewer must be called first.
  • The state is synced with throttling (default 8ms), not per frame; the returned vectors/coordinates are cloned, so mutating them does not affect the camera.
  • In positionCartographic, longitude/latitude are in radians (may fall outside valid ranges in 2D and Columbus View); level is estimated from height with an empirical formula, not an official Cesium API.

Type Definitions ​

typescript
import type { Camera, Cartesian3, Cartographic, Rectangle } from 'cesium';
import type { ComputedRef, MaybeRefOrGetter } from 'vue';
export interface UseCameraStateOptions {
    /**
     * The camera to use
     * @default useViewer().value.scene.camera
     */
    camera?: MaybeRefOrGetter<Camera | undefined>;
    /**
     * Camera event type to watch
     * @default `changed`
     */
    event?: MaybeRefOrGetter<'changed' | 'moveStart' | 'moveEnd'>;
    /**
     * Throttled delay duration (ms)
     * @default 8
     */
    delay?: number;
}
export interface UseCameraStateReturn {
    /**
     * The camera
     */
    camera: ComputedRef<Camera | undefined>;
    /**
     * The position of the camera
     */
    position: ComputedRef<Cartesian3 | undefined>;
    /**
     * The view direction of the camera
     */
    direction: ComputedRef<Cartesian3 | undefined>;
    /**
     * The up direction of the camera
     */
    up: ComputedRef<Cartesian3 | undefined>;
    /**
     * The right direction of the camera
     */
    right: ComputedRef<Cartesian3 | undefined>;
    /**
     * Gets the {@link Cartographic} position of the camera, with longitude and latitude
     * expressed in radians and height in meters.  In 2D and Columbus View, it is possible
     * for the returned longitude and latitude to be outside the range of valid longitudes
     * and latitudes when the camera is outside the map.
     */
    positionCartographic: ComputedRef<Cartographic | undefined>;
    /**
     * Gets the position of the camera in world coordinates
     */
    positionWC: ComputedRef<Cartesian3 | undefined>;
    /**
     * Gets the view direction of the camera in world coordinates
     */
    directionWC: ComputedRef<Cartesian3 | undefined>;
    /**
     * Gets the up direction of the camera in world coordinates
     */
    upWC: ComputedRef<Cartesian3 | undefined>;
    /**
     * Gets the right direction of the camera in world coordinates
     */
    rightWC: ComputedRef<Cartesian3 | undefined>;
    /**
     * Computes the approximate visible rectangle on the ellipsoid
     */
    viewRectangle: ComputedRef<Rectangle | undefined>;
    /**
     * Gets the camera heading in radians
     */
    heading: ComputedRef<number | undefined>;
    /**
     * Gets the camera pitch in radians
     */
    pitch: ComputedRef<number | undefined>;
    /**
     * Gets the camera roll in radians
     */
    roll: ComputedRef<number | undefined>;
    /**
     * Gets the camera center hierarchy level
     */
    level: ComputedRef<number | undefined>;
}
/**
 *  Reactive Cesium Camera state
 * @param options options
 * @returns Reactive camera states
 */
export declare function useCameraState(options?: UseCameraStateOptions): UseCameraStateReturn;