Skip to content

HexagonSpreadScanEffect 六边形扩散扫描

半径周期性增长的六边形扫描脉冲效果。以椭圆实体承载六边形渐变纹理材质,长短轴半径 每帧步进增长(+8 米),超过最大半径后归 0.1 米重新循环,形成六边形扩散扫描脉冲。 对齐源案例 SpecialEffects/HexagonSpreadScan。


能力定位

HexagonSpreadScanEffect 适合:

  • 六边形扩散扫描:六边形渐变脉冲从中心向外扩散,模拟区域扫描;
  • 区域 / 信号覆盖可视化:周期性扩散的能量或探测范围示意;
  • CircleSpreadScanEffect 并列的扩散变体:圆形扩散用圆环纹理, 本效果用六边形纹理,视觉辨识更强。

CircleSpreadScanEffect(圆形扩散扫描,时间百分比动画)不同, 本效果采用帧步进动画(每帧 +8 米,帧间节奏由渲染帧驱动),且长短轴共享同一 CallbackProperty 实例 —— 保证任意时刻 semiMajorAxis === semiMinorAxis, 满足 Cesium 1.133 的 EllipseGeometry 校验。

构造函数

ts
constructor(options: HexagonSpreadScanEffectOptions)
ts
interface HexagonSpreadScanEffectOptions {
  position: Cartesian3 // 扫描中心位置(世界坐标)
  radius?: number      // 最大扩散半径(米),默认 200
  color?: Color        // 扫描颜色,默认 Color.RED
  image?: string       // 六边形渐变纹理 URL,默认 /static/images/effects/hexagon.png
}
参数类型默认值描述
positionCartesian3扫描中心位置(世界坐标),必填,缺省抛错
radiusnumber200最大扩散半径(米),半径动画的上界
colorColorColor.RED扫描颜色(材质叠加于六边形纹理上)
imagestring/static/images/effects/hexagon.png六边形渐变纹理图片 URL

生命周期

实现 Lifecycle<Viewer> 契约,on/off/destroy 均幂等:

ts
on(viewer: Viewer): void      // 创建椭圆实体,长短轴共享半径动画
off(viewer: Viewer): void     // 移除本效果创建的全部实体
destroy(viewer: Viewer): void // 等价于 off

动画复位on 每次启用时半径状态从 0.1 米重新开始(对齐源案例 new HexagonSpreadScan 即新建闭包的行为)。off 后再次 on,动画从头循环。

基础示例

ts
import { HexagonSpreadScanEffect } from '@nexa/gis-cesium'
import { Cartesian3, Color } from 'cesium'

const effect = new HexagonSpreadScanEffect({
  position: Cartesian3.fromDegrees(120, 30, 0),
  radius: 500,
  color: Color.RED.withAlpha(0.6),
})
effect.on(viewer)

进阶示例

多色多中心六边形扩散扫描组合(对齐源案例三色脉冲):

ts
import { HexagonSpreadScanEffect } from '@nexa/gis-cesium'
import { Cartesian3, Color } from 'cesium'

const centers = [
  { lon: 104.0615, lat: 30.6705, color: Color.RED },
  { lon: 104.0730, lat: 30.6540, color: Color.AQUA },
  { lon: 104.0860, lat: 30.6720, color: Color.YELLOW },
]
const effects = centers.map(({ lon, lat, color }) => {
  const fx = new HexagonSpreadScanEffect({
    position: Cartesian3.fromDegrees(lon, lat, 0),
    radius: 500,
    color,
  })
  fx.on(viewer)
  return fx
})

// 演示到期后统一销毁,释放全部实体
window.setTimeout(() => {
  effects.forEach(fx => fx.destroy(viewer))
}, 120000)

实现说明

  • 帧步进动画:半径推进由 viewer.clock.onTick 驱动 —— Viewer 渲染循环每帧调用 clock.tick() 并触发该事件(与 shouldAnimate 无关),每帧恰好推进一次 +8; 超过最大半径归 0.1 循环;
  • 推进与求值解耦CallbackProperty无副作用纯读取,只返回当前半径,绝不 在属性求值内部修改状态 —— 长短轴在同一 geometry 构造周期内任意次数/顺序求值都读到 同一值,semiMajorAxis === semiMinorAxis 恒成立,杜绝 EllipseGeometrymajor >= minor 的断言崩溃;
  • 为何不沿用源的双闭包:源案例(短轴闭包内推进 +8、长轴读共享变量)在 Cesium 1.72 可运行,但 1.133 下长短轴求值若跨毫秒会让短轴多推进一次 → major < minor 崩溃; 本实现把推进移到渲染帧信号上,算法语义与源逐帧一致但不再有竞态;
  • 逐帧与源一致:同一最大半径输入下,半径序列与源案例动画逐帧差分 maxDiff = 0 (差分验证见模块单测);
  • 材质复用:直接复用 HexagonSpreadScanMaterialProperty(六边形渐变纹理 + alpha * 0.5diffuse * 1.8 的扩散着色),效果类不重复材质逻辑;
  • 资源所有权:本效果创建的全部实体由 off/destroy 移除,创建方无需单独清理。

清理责任

ts
effect.destroy(viewer) // 或 effect.off(viewer),等价且幂等

重复调用 destroy/off 安全(无实体时为空操作)。

Cesium 版本限制

  • 依赖 Cesium Entity.ellipseEllipseGraphics)与 CallbackProperty
  • 材质依赖 HexagonSpreadScanMaterialProperty(本 SDK 内置,含 HexagonSpreadScan 材质注册);
  • 已验证目标版本:Cesium 1.133.1。