跳至内容

useElementOverlay

把 HTML 元素锚定到 Cesium 场景中的某个地理坐标,并随相机变化实时更新位置。基于 scene.postUpdate 每帧自动同步,内置对齐(horizontal/vertical)、像素偏移(offset)、贴地(clampToGround)与坐标系选择,返回 x/y/style 并默认自动应用到目标元素。

Usage

vue
<script lang="ts" setup>
import * as Cesium from 'cesium';
import { useElementOverlay, useEntity, useViewer } from 'vesium';
import { shallowRef, watchEffect } from 'vue';

const viewer = useViewer();
const position = shallowRef(Cesium.Cartesian3.fromDegrees(100.04215139520794, 31.320830427363237, 0));

watchEffect(async () => {
  if (viewer.value?.scene) {
    viewer.value.scene.terrainProvider = await Cesium.createWorldTerrainAsync();
  }
});

useEntity(new Cesium.Entity({
  position: position.value,
  point: {
    pixelSize: 10,
    color: Cesium.Color.YELLOW,
    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  },
}));

watchEffect(() => {
  viewer.value?.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(100.04215139520794, 31.320830427363237, 100000),
  });
});

const elRef = shallowRef<HTMLDivElement>();

const { x, y, style } = useElementOverlay(elRef, position, {
  offset: { x: 0, y: -20 },
  clampToGround: true,
});
</script>

<template>
  <teleport v-if="viewer" :to="viewer?.container">
    <div ref="elRef" class="text-white p-20px bg-black/50 absolute">
      <h4>useElementOverlay</h4>
      <pre>{{ JSON.stringify({ x, y, style }, undefined, 2) }}</pre>
    </div>
  </teleport>
</template>
vue
<script setup lang="ts">
import * as Cesium from 'cesium';
import { useElementOverlay } from 'vesium';
import { shallowRef } from 'vue';

const elRef = shallowRef<HTMLDivElement>();
const position = shallowRef(Cesium.Cartesian3.fromDegrees(120, 30, 0));
const { x, y, style } = useElementOverlay(elRef, position, { offset: { x: 0, y: -20 } });
</script>

<template>
  <div ref="elRef" class="absolute" :style="style">
    My Label
  </div>
</template>

配置项

  • horizontal / vertical - 水平/垂直对齐原点,默认 'center' / 'bottom';可选 'center' | 'left' | 'right' / 'center' | 'bottom' | 'top'
  • offset - 锚点基础上的像素偏移,默认 { x: 0, y: 0 }
  • referenceWindow - true 时相对浏览器视口定位(加上 canvas 在页面中的位置),缺省相对 Cesium 画布。
  • applyStyle - 是否自动把 left/top 应用到目标元素,默认 true;设为 false 时自行绑定返回的 x/y/style
  • clampToGround - 是否把坐标贴到地表(通过 scene.clampToHeight),需要地形或 3D Tiles 等高度数据。

返回值

  • x / y - 像素坐标(ComputedRef<number>,保留 1 位小数,已按对齐原点扣除元素自身尺寸);style - 可直接绑定到元素的 CSS 字符串(如 left:100px;top:200px;)。

注意事项

  • clampToGround 依赖 scene.clampToHeight,地形未加载或无法贴地时回退为原始坐标;demo 使用世界地形展示该效果,需要网络连接与 Ion token。

Type Definitions

typescript
import type { CommonCoord } from '@vesium/shared';
import type { MaybeComputedElementRef } from '@vueuse/core';
import type { ComputedRef, MaybeRefOrGetter } from 'vue';
export interface UseElementOverlayOptions {
    /**
     * Horizontal origin of the target element
     * @default `center`
     */
    horizontal?: MaybeRefOrGetter<'center' | 'left' | 'right' | undefined>;
    /**
     * Vertical origin of the target element
     * @default `bottom`
     */
    vertical?: MaybeRefOrGetter<'center' | 'bottom' | 'top' | undefined>;
    /**
     * Pixel offset presented by the target element
     * @default {x:0,y:0}
     */
    offset?: MaybeRefOrGetter<{
        x?: number;
        y?: number;
    } | undefined>;
    /**
     * The reference element for calculating the position of the target element
     *  - `true` refer to the browser viewport
     *  - `false` refer to the Cesium canvas
     */
    referenceWindow?: MaybeRefOrGetter<boolean>;
    /**
     * Whether to apply style to the target element
     * @default true
     */
    applyStyle?: MaybeRefOrGetter<boolean>;
    /**
     * The position will be clamped to the ground
     *
     */
    clampToGround?: MaybeRefOrGetter<boolean>;
}
export interface UseElementOverlayReturn {
    /**
     * Calculation result of the target element's horizontal direction
     */
    x: ComputedRef<number>;
    /**
     * Calculation result of the target element's vertical direction
     */
    y: ComputedRef<number>;
    /**
     * Calculation `css` of the target element
     */
    style: ComputedRef<string | undefined>;
}
/**
 * Cesium HTMLElement Overlay
 */
export declare function useElementOverlay(target?: MaybeComputedElementRef, position?: MaybeRefOrGetter<CommonCoord | undefined>, options?: UseElementOverlayOptions): UseElementOverlayReturn;