release: bump version to 0.46.0

This commit is contained in:
rayd1o
2026-04-30 04:42:29 +08:00
parent ba54545ac7
commit b1a5934b80
29 changed files with 2351 additions and 1095 deletions

View File

@@ -26,6 +26,7 @@
- [earth-news-source-configuration-and-collector-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-news-source-configuration-and-collector-plan.md)
- [earth-news-cruise-summary-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-news-cruise-summary-plan.md)
- [earth-vessel-rendering-performance-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-vessel-rendering-performance-plan.md)
- [earth-interactable-layer-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-interactable-layer-plan.md)
- [frontend-public-docs-site-plan.md](/home/ray/dev/linkong/planet/docs/plans/frontend-public-docs-site-plan.md)
- [frontend-ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/plans/frontend-ai-playground-development-plan.md)
- [ue5-mvp-fused-plan.md](/home/ray/dev/linkong/planet/docs/plans/ue5-mvp-fused-plan.md)

View File

@@ -0,0 +1,312 @@
# Earth Interactable Layer Plan
## 背景
状态Phase 1 已经开始落地Phase 2 的 BGP 事件 / 观测站迁移和 Phase 3 的算力中心迁移也已完成。`frontend/public/earth/js/interactable.js` 已新增AIS 船只、BGP 事件、BGP 观测站和算力中心图层已经改为通过 `createInteractableLayer()` 使用通用批量 `Points`、hover / locked overlay、默认 glow、状态更新、asset icon 预加载、屏幕空间 picking、固定 / 距离缩放和跨 Interactable 同坐标避让。登陆点因 `THREE.Points` 边缘深度裁切和贴地层级要求,已退回专用 `THREE.Sprite` 黄色球路径,并与海缆同高度同 renderOrder。后续阶段聚焦把可复用的扩圈 / 雷达扇形动画正式沉淀成 `animations` 扩展。
当前实现说明和接入示例见:
- [earth-interactable-usage.md](/home/ray/dev/linkong/planet/docs/technical/zh/earth-interactable-usage.md)
当前 AIS 船只图层已经形成了一个适合作为基准的交互图标模式:
- 普通态使用批量 `THREE.Points` 渲染,避免每个对象一个 `Sprite` 带来的 draw call 和透明排序压力。
- hover / locked 态使用单点 overlay 叠加 glow不改变普通批次交互反馈清晰且成本低。
- moving / anchored 船只通过 canvas 点纹理表达不同形状moving 船只还按航向分桶。
- 拾取走屏幕空间命中,拖动和惯性期间跳过高频 hover picking。
- 图层高度贴近地表,仅保留很小的深度余量,避免“浮在表面层”的观感。
这个模式不应该只服务船只。后续 BGP 事件、BGP 观测站、算力中心、新闻事件、告警、地面传感器等都可能需要“图标类可交互元素”。如果每个图层继续各写一套 icon、glow、hover、locked、动画、picking 和图例逻辑,视觉会漂移,性能策略也会重复分叉。登陆点已经验证为例外:需要完整贴地且不被球面边缘裁切时,专用 Sprite 路径比通用 `Points` 更合适。
目标是把船只图层的成功做法抽象成一个通用接口:业务图层只描述“要画什么、在哪里、怎么交互”,底层统一负责批量渲染、默认 glow、状态 overlay、动画槽位、拾取和生命周期。
## 目标
1. 建立统一的 Earth 交互图标接口,作为未来地表图标类元素的默认入口。
2. 以 AIS 船只 glow 为默认 glow 视觉,其它图标默认沿用同一套 glow 质感。
3. 保留图标颜色、状态颜色、hover 放大、locked 强调、dimmed 聚焦、动画扩展等能力。
4. 支持 canvas / SVG / image icon不强行要求所有图标都可重着色。
5. 保持船只当前性能路线:批量绘制普通态,少量 overlay 处理交互态。
6. 给 BGP 事件扩圈、BGP 观测站雷达扇形等补充动画留出正式扩展点。
## 非目标
- 不在第一阶段重写所有 Earth 图层。
- 不把卫星、海缆、国家边界、真实地形这类非图标图层纳入同一个接口。
- 不为了抽象牺牲业务图标的差异表达例如船只航向、BGP 事件严重级别、观测站雷达扫掠。
- 不要求图片图标支持运行时重着色;图片图标只能通过预制多状态图片或 overlay tint 做有限表达。
## 核心设计
建议新增一个通用模块,例如:
```text
frontend/public/earth/js/interactable.js
```
它导出一个工厂或注册函数:
```js
createInteractableLayer({
id,
earth,
renderOrder,
altitudeOffset,
icon,
scale,
glow,
colors,
states,
animations,
picking,
data,
getPosition,
getKind,
getRotation,
getPayload,
});
```
业务模块仍保留自己的数据加载、图例、详情卡字段和业务语义。例如 `vessels.js` 负责 AIS 数据和船型映射,但 icon 渲染、hover overlay、locked overlay、默认 glow 和屏幕空间 picking 可以逐步迁入 `interactable.js`
## 参数草案
| 参数 | 类型 / 示例 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `id` | `"vessels"` | 必填 | 图层唯一标识,用于 debug、picking、legend 和状态缓存。 |
| `earth` | `THREE.Object3D` | 必填 | 图层挂载目标,通常是 Earth root。 |
| `renderOrder` | `4.4` | `4` | 普通 icon 批次和 overlay 的基础渲染顺序。 |
| `altitudeOffset` | `0.2` | `0.2` | 图层高度,语义为 `CONFIG.earthRadius + altitudeOffset`。地表图标默认贴近真实地形基础层。 |
| `icon` | `{ type, source, draw, size, bins }` | 必填 | 图标来源。支持 canvas draw、SVG URL、image URL、内置 shape。 |
| `icon.fitSize` | `60``{ width: 60, height: 60 }` | `atlasCellSize` | asset 图标在 atlas canvas 内的最大绘制尺寸,默认居中等比 contain。SVG / 图片文件只负责原始形状,不需要为了显示大小手写 transform。 |
| `scale` | `{ base, min, max }` | `{ base: 1 }` | 基础缩放和距离稳定范围。当前船只可映射到 `VESSEL_POINT_SIZE` / `baseScale`。 |
| `sizeMode` | `"fixed" / "distance"` | `"fixed"` | 是否固定屏幕像素尺寸;非 fixed 时按相机到地表距离做比例缩放。 |
| `sizeScale` | `{ min, max, referenceFov }` | `{ min: 0.12, max: 3, referenceFov: 75 }` | `sizeMode !== "fixed"` 时的缩放限制和参考视角。 |
| `glow.enabled` | `true / false` | `true` | 是否启用默认 glow。默认 glow 以船只 hover / locked overlay 为基准。 |
| `glow.intensity` | `0.0 - 2.0` | `1` | glow 强度,内部映射到 canvas `shadowBlur`、opacity 或 shader uniform。 |
| `glow.colorMode` | `"state" / "icon" / "fixed"` | `"state"` | glow 颜色来源,默认跟随状态颜色。 |
| `hover.scale` | `1.0 - 2.0` | `1.18` | hover 放大倍率。当前船只保持同尺寸 glow overlay接口仍保留放大能力供其它图层使用。 |
| `hover.mode` | `"scale" / "glow-only" / "custom"` | `"scale"` | hover 反馈方式。船只可用 `"glow-only"`,其它图标默认放大。 |
| `colors.normal` | `"#4A90D9"` | icon 原色 | 普通态颜色。只有可上色 icon 生效。 |
| `colors.hover` | `"#7dd3fc"` | normal | hover 态颜色。 |
| `colors.locked` | `"#ffffff"` | hover | locked 态颜色。 |
| `colors.dimmed` | `"#9B9B9B"` | normal | 聚焦其它对象时的弱化颜色。 |
| `colors.byKind` | `{ cargo: "#4A90D9" }` | `{}` | 按业务类型着色如船型、BGP 严重级别。 |
| `colorable` | `true / false` | 由 icon 类型推断 | canvas shape 和 SVG mask 通常可上色;图片默认不可上色。 |
| `opacity` | `{ normal, hover, locked, dimmed }` | 船只当前值 | 各状态透明度。 |
| `rotation` | `{ enabled, bins, getAngle }` | disabled | 是否按角度分桶,例如船只按 COG 分 32 桶。 |
| `animations` | `IconAnimationSpec[]` | `[]` | 补充动画列表,例如扩圈、雷达扇形、脉冲、轨迹尾迹。 |
| `picking.radiusPx` | `22` | `20` | 屏幕空间命中半径。 |
| `picking.throttleMs` | `100` | `80` | hover picking 节流。 |
| `picking.skipWhileDragging` | `true` | `true` | 拖动和惯性期间跳过 hover picking。 |
| `zIndexPolicy` | `"surface-icon"` | `"surface-icon"` | 预设层级策略,避免每个业务图层手写高度和 renderOrder。 |
| `avoidance.enabled` | `true / false` | `true` | 是否参与跨 Interactable 的同坐标避让。默认开启,同一经纬度下的图标会沿地表切平面小幅排开,方便辨认和选择。 |
| `avoidance.radius` | `number` | `1.1` | 同坐标避让的第一圈半径,单位为地球本地坐标单位。 |
| `avoidance.precision` | `number` | `4` | 经纬度归并精度,默认约等于只处理几乎完全重叠的图标。 |
| `legend` | `{ label, color, shape }[]` | `[]` | 可选图例声明,业务层也可以继续自己导出。 |
| `metadata` | object | `{}` | 业务扩展数据,不参与渲染但参与 tooltip / info-card / search。 |
## Icon 规格
图标输入建议分三类:
```js
{
type: "canvas-shape",
size: 128,
draw(ctx, state) {
// draw triangle / dot / custom shape
},
}
```
```js
{
type: "svg-mask",
source: "/earth/assets/icons/bgp-event-dot.svg",
colorable: true,
}
```
```js
{
type: "image",
source: "/earth/assets/icons/vendor-logo.png",
colorable: false,
stateSources: {
hover: "/earth/assets/icons/vendor-logo-hover.png",
},
}
```
颜色策略:
- `canvas-shape` 默认可上色,适合船只、事件点、雷达站这类符号。
- `svg-mask` 如果能作为 mask 使用,则可上色;如果是完整多色 SVG则按图片处理。
- `image` 默认不可上色;需要状态变化时使用 `stateSources` 或额外 glow / ring。
## 默认 Glow 规范
默认 glow 以当前船只 overlay 为视觉基准:
- 普通态尽量不启用 glow保持地图干净。
- hover / locked 态叠加同位置 overlay。
- glow 颜色默认跟随状态颜色或业务类型颜色。
- glow blur 应该稳定,不随 camera zoom 夸张膨胀。
- 允许通过 `glow.intensity` 控制强度,但不要让业务图层各自发明完全不同的光晕语言。
建议内部把 glow 拆成两个层次:
1. `textureGlow`canvas texture 里的 `shadowBlur`,适合小图标 hover / locked。
2. `effectGlow`:额外 ring / halo / pulse适合告警、BGP 事件和锁定强调。
## 状态模型
通用状态至少包含:
| 状态 | 触发 | 默认表现 |
| --- | --- | --- |
| `normal` | 普通显示 | 批量 Points使用 normal 颜色和 opacity。 |
| `hover` | 指针悬停 | 默认放大并显示 glow船只可配置为同尺寸 glow-only。 |
| `locked` | 点击锁定 / 详情打开 | 强 glow、更高 opacity可选 ring 或 pulse。 |
| `dimmed` | 聚焦其它对象 | 降低 opacity保留上下文。 |
| `hidden` | 图层关闭或过滤 | 不参与绘制和 picking。 |
| `alert` | 业务告警 | 可叠加动画,不替代 locked 状态。 |
状态更新需要增量化:只在 hover 目标、locked 目标、过滤条件、数据版本或相机距离阈值变化时更新,不在每帧遍历全部 icon 写材质属性。
## 动画扩展
动画不直接塞进 icon 基础参数,而是作为 `animations` 列表注册。每个动画声明自己的 geometry / material / update 策略:
```js
{
type: "expanding-ring",
when: ["alert", "locked"],
color: "state",
radiusPx: [10, 42],
durationMs: 1400,
opacity: [0.8, 0],
}
```
```js
{
type: "radar-sweep",
when: ["normal", "hover", "locked"],
angleDeg: 72,
rotationMs: 2600,
opacity: 0.36,
}
```
首批建议内置动画:
| 动画 | 用例 | 说明 |
| --- | --- | --- |
| `pulse-ring` | locked、告警点 | 原地呼吸环,强调选中对象。 |
| `expanding-ring` | BGP 事件 | 向外扩散的事件波纹。 |
| `radar-sweep` | BGP 观测站 | 扇形扫描,可持续旋转。 |
| `orbiting-dot` | 数据流 / collector 活跃态 | 小点绕 icon 环绕,表达活动状态。 |
| `trail` | 移动目标 | 可选短尾迹,船只或飞机类目标使用。 |
动画必须支持批量或分组绘制,避免为每个对象创建独立的高频更新对象。只有 locked / hover / 少量 alert 对象可以使用单对象 overlay。
## 渲染策略
### 普通态
普通态优先使用分桶 `THREE.Points`
- 按 icon 类型、可上色策略、旋转分桶、纹理 key 分组。
- 每组一个 `BufferGeometry`,存 `position``color`、必要的 `payloadIndex`
- `PointsMaterial.sizeAttenuation = false`,保持屏幕尺寸稳定。
- `depthTest = true``depthWrite = false`,避免遮挡关系破坏地表。
### 交互态
hover / locked 使用少量 overlay
- overlay 复用 `THREE.Points` 单点对象或小型 ring mesh。
- overlay texture 从统一 cache 获取。
- overlay 更新只写当前 hover / locked 的 position、texture、opacity、size。
### 高密度升级
当某类图标超过分桶 Points 的舒适区,才考虑升级:
- `InstancedBufferGeometry` billboard。
- 自定义 shader 支持 per-instance rotation / scale / opacity。
- 视口 bbox / LOD / cluster。
这个升级不应该改变业务接口,只替换底层 renderer。
## Picking 策略
沿用船只当前方向:
- 默认屏幕空间 picking而不是 Three.js 对每个 Sprite / Points 做 raycast。
- 每个 icon 保留世界坐标和业务 payload。
- 每次 pointer move 将候选点投影到屏幕,按半径和深度判断命中。
- 拖动、惯性旋转、相机剧烈变化期间跳过 hover picking。
- click 时允许做一次更精确的 picking。
后续可以按图层或经纬度网格增加空间索引,减少候选点数量。
## 与现有图层的迁移路径
### Phase 1抽出船只基准能力
-`vessels.js` 提取 texture cache、canvas icon draw、overlay glow、分桶 Points 创建、状态增量更新。
- 保持 `vessels.js` 的公开 API 不变:`loadVessels()``toggleVessels()``getVesselMarkers()` 等继续可用。
- 新模块先只服务船只,确保视觉没有回退。
### Phase 2迁移 BGP 事件和观测站
- BGP 事件使用 `canvas-shape`,已接入 `Interactable`
- 严重级别映射到 `colors.byKind`,并通过通用 `getPointSizeMultiplier` 保留严重级别尺寸倍率。
- 当前扩圈效果保留在 BGP 业务动画中,并跟随 `Interactable` marker 位置更新。
- BGP 观测站主图标已接入 `Interactable`,活跃度映射到颜色和 `getPointSizeMultiplier`
- BGP 观测站 halo / 覆盖扇形继续由 BGP 业务动画表达扫描,并跟随 `Interactable` marker 位置更新。
### Phase 3迁移算力中心并评估登陆点
- 算力中心保留现有业务 icon但接入统一 hover / locked / glow。已完成
- 登陆点曾接入同一套 `Points` 渲染,但 pin 类 SVG 在地球边缘会被深度测试裁切;当前保留专用 `THREE.Sprite`,并使用 canvas 生成黄色扁平球,贴到海缆层级。后续如要重新设计登陆点,需要先确认图标能在边缘视角完整显示。
- 检查图例、搜索和 info-card 是否只依赖业务 payload而不是依赖渲染对象类型。
### Phase 4形成 Earth 图标层规范
-`docs/technical/zh/earth-frontend-context.md` 记录当前实现入口。
-`docs/technical/zh/earth-layer-style-reference.md` 记录默认 glow、状态颜色、默认高度和动画参数。
-`docs/technical/zh/earth-render-layer-order.md` 记录 surface icon renderOrder 范围。
## 风险与约束
- 过早抽象可能让船只这种高质量基准被平均化,因此第一阶段必须以船只视觉不回退为验收标准。
- 图片 icon 不可上色,接口需要明确 `colorable = false` 的行为,避免业务层误以为颜色一定生效。
- 动画如果默认开启过多,会重新引入 overdraw 和每帧更新压力;默认只给 hover / locked 或少量 alert 使用。
- 地形开启时,贴地 icon 需要在高度、`depthTest``polygonOffset` 和 renderOrder 之间保持平衡。
- 统一 glow 不等于所有图标一模一样;业务可以调强度和颜色,但不应破坏整体视觉语言。
## 验收标准
1. 船只迁入通用接口后普通态、hover、locked、航向、颜色、轨迹和 picking 行为保持一致。
2. 新增一个 BGP 事件示例图层配置,不需要复制船只渲染代码即可得到 icon、glow、hover 和扩圈动画。
3. 新增一个 BGP 观测站示例图层配置,不需要自写独立动画循环即可得到雷达扇形。
4. 关闭图层后对应 icon、overlay、动画和 picking 全部停止。
5. 高密度数据下普通态仍走批量绘制hover / locked 只更新少量 overlay。
6. 文档同步说明默认高度、默认 glow、状态模型和动画扩展点。
## 相关文件
| 文件 | 当前角色 | 未来关系 |
| --- | --- | --- |
| `frontend/public/earth/js/vessels.js` | 船只基准实现,包含分桶 Points、hover / locked overlay、默认 glow 形态 | Phase 1 的抽象来源 |
| `frontend/public/earth/js/constants.js` | 保存船只高度、颜色、透明度、轨迹参数 | 后续可加入通用 surface icon 默认配置 |
| `frontend/public/earth/js/bgp.js` | BGP 事件和观测站视觉逻辑 | BGP 事件和观测站主图标已接入 Interactable扩圈、halo 和覆盖扇形仍保留业务动画 |
| `frontend/public/earth/js/compute-centers.js` | 算力中心 icon 和交互 | 已通过 Interactable 接入统一 Points、overlay、glow 和 picking |
| `frontend/public/earth/js/cables.js` | 登陆点 icon 和海缆线 | 登陆点当前使用专用 `THREE.Sprite` 黄色球,不再走 Interactable海缆线仍独立渲染 |
| `frontend/public/earth/js/main.js` | 当前集中处理 hover、click、locked 和 info-card 入口 | 后续需要接入通用 icon picking 结果 |
| `docs/technical/zh/earth-layer-style-reference.md` | 当前视觉参数参考 | 实现后同步默认 glow 和通用参数 |
| `docs/technical/zh/earth-render-layer-order.md` | 当前层级参考 | 实现后同步 surface icon 层级范围 |