Appearance
AnimatePointEffect 动画点位效果
在指定经纬度位置上叠加一个带脉冲涟漪动画的 DOM 圆点标记。基于
scene.postRender每帧将世界坐标投影为屏幕坐标并刷新 DOM 位置,形成持续扩散的涟漪效果。
能力定位
AnimatePointEffect 适合:
- 重点点位标记:目标、兴趣点、事件位置;
- 大屏态势展示:多点位定位涟漪,突出关注目标;
- 与实体配合:作为 DOM overlay 叠加在 Cesium 实体之上,不占用 GPU 资源。
与 特效系统 中的实体类效果不同,本效果使用 DOM overlay,通过 注入的 @keyframes 动画实现涟漪,适合数量较少、需要自定义 CSS 外观的点位。
构造函数
ts
constructor(options: AnimatePointEffectOptions)ts
interface AnimatePointEffectOptions {
position: Cartesian3; // 点位位置(世界坐标),必填
cssColor?: string; // CSS 颜色,默认 '#ff0000'
maxVisibleHeight?: number; // 相机高度超过该值后隐藏(米),默认 80000
}| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
position | Cartesian3 | — | 点位世界坐标,缺少时构造抛错 |
cssColor | string | '#ff0000' | 点位及涟漪颜色,任意合法 CSS 颜色值 |
maxVisibleHeight | number | 80000 | 相机高度超过该阈值后隐藏点位,避免高空视角下 DOM 标记失去意义 |
生命周期
ts
on(viewer: Viewer): void // 启用效果,创建 DOM 与样式,注册 postRender 监听(幂等)
off(viewer: Viewer): void // 停用效果,移除监听、DOM 与注入的样式(幂等)
destroy(viewer: Viewer): void // 销毁效果,委托 off 释放全部自有资源(可重复调用)| 方法 | 参数 | 说明 |
|---|---|---|
on | viewer | 重复调用为 no-op,不会重复创建资源 |
off | viewer | 未启用时调用为 no-op |
destroy | viewer | 委托 off,重复调用安全 |
基础示例
ts
import { AnimatePointEffect } from '@nexa/gis-cesium'
import { Cartesian3 } from 'cesium'
const effect = new AnimatePointEffect({
position: Cartesian3.fromDegrees(118.76, 32.03, 0),
cssColor: '#ff0000',
})
effect.on(viewer)
// 页面或场景退出时由创建方负责清理
effect.destroy(viewer)进阶示例
多点位、多颜色标记,模拟城市态势分布:
ts
import { AnimatePointEffect } from '@nexa/gis-cesium'
import { Cartesian3 } from 'cesium'
const positions = [
{ lng: 118.76, lat: 32.03, color: '#ff0000' },
{ lng: 118.78, lat: 32.05, color: '#ffa500' },
{ lng: 118.72, lat: 32.01, color: '#00ff7f' },
]
const effects = positions.map(({ lng, lat, color }) => {
const fx = new AnimatePointEffect({
position: Cartesian3.fromDegrees(lng, lat, 0),
cssColor: color,
})
fx.on(viewer)
return fx
})
// 场景退出时统一清理
effects.forEach(fx => fx.destroy(viewer))可见性规则
与源案例一致,点位只在满足以下两个条件时显示:
- 相机到点位的距离 ≤
相机高度 + 地球最大半径(避免点位在地球背面时仍显示); - 相机高度 <
maxVisibleHeight(默认 80000 米)。
ts
const carto = viewer.scene.globe.ellipsoid.cartesianToCartographic(viewer.camera.position)
const cameraHeight = carto ? carto.height : 0
const distance = Cesium.Cartesian3.distance(viewer.camera.position, this._position)
const visible =
distance <= cameraHeight + viewer.scene.globe.ellipsoid.maximumRadius &&
cameraHeight < this._maxVisibleHeight实现与性能说明
- DOM overlay:效果在
viewer.cesiumWidget.container上叠加绝对定位的div,pointer-events: none穿透,不阻挡场景交互; - 样式注入:涟漪动画的
@keyframes按实例生成唯一名称并注入<style>,off()时移除。多个效果可并存互不干扰,无需宿主页面引入外部 CSS; - 坐标投影:使用
SceneTransforms.worldToWindowCoordinates(Cesium 1.133 已移除 旧版wgs84ToWindowCoordinates); - 资源所有权:效果只创建并释放自己的 DOM 节点、注入样式与 postRender 监听, 不触碰 viewer 实体或图层。
Cesium 版本限制
- 需要 Cesium ≥ 1.100(
SceneTransforms.worldToWindowCoordinates可用); - 已验证目标版本:Cesium 1.133.1。
清理责任
on()创建的 DOM、样式与监听,统一由destroy(viewer)(或off(viewer))释放;- 不调用
destroy会导致 postRender 监听与 DOM 残留,务必在页面或场景退出时清理; destroy可重复调用,幂等安全。
与原生 Cesium API 的组合方式
- 可与
viewer.entities.add()的 point/label 实体叠加使用,作为实体位置的醒目 DOM 标记; - 需要跟随场景其他元素时,直接创建多个
AnimatePointEffect实例即可,无共享状态。