/** * 地图标记 DOM overlay(票 47)——billboard 发糊与底板生硬的结构性解决。 * * 渲染分工(维护者 2026-10-15 裁定): * · **外层母版 = 自绘 SVG**(矢量,任何 DPR 都锐利;billboard 发糊的根治)。 * 水滴形按实测母版几何拟合:帽圆 (188.5,189) r189(逐行验证误差 <1px)+ * 下半收尖三次贝塞尔(对 512px 母版左缘 57 点最小二乘拟合,最大残差 4.75 源像素 * ≈ 0.34 屏显像素;拟合探针见 .scratch/cockpit-real-data-wayfinding/research/fit-pin-bezier.mjs)。 * 镂空孔 = 实测圆 (188.5,189) r75。viewBox 外扩 40 与 billboard 裁剪窗(OUTLINE_PAD)同形。 * · **内层行业图标 = 素材**(`markerAssets.renderInnerIconUrl`:与 billboard 同一 * `recolorInner` 去色重染规则,但**不下采样**——256px 原生分辨率 data URL, * DOM 里按帽径向下采样,永远锐利)。 * · 标签 = 真 DOM(圆角底板、装饰边、text-overflow、hover title 原生能力)。 * · 每帧 `postRender` 投影:与 billboard `CLAMP_TO_GROUND` 同口径(地形实测高程,取不到回椭球 0)。 * * 与既有链路的关系(维护者裁定:DOM 完整复刻 billboard 功能后才替换它): * · 合成计划层 `domain/markerPlan.js` **原样复用**(归属/几何/锚点/降饱和不换媒介); * · `syncPointMarkersForPlan`(billboard 链路)**保留不动**——聚合、特效、Canvas 拾取仍依赖它; * 内层素材加载失败时 SVG 只有母版 = 底下 billboard 双层照常显示(降级可见); * · 拾取:overlay 节点挂**显式 click 触发器**,回调直接复用 `pickDeviceOrPointAt` * (与 Canvas 点选链同一个功能函数,维护者原话「照搬原本的功能函数」); * · `data-*` 断言面全部挂到 DOM 节点,走查不读内部实现。 * * 性能纪律:节点池复用(不每帧重建);计划读数指纹变化才重建;postRender 只做 transform 更新。 */ import { renderInnerIconUrl } from './markerAssets.js' // 票 76(C1 → 统一渲染):聚合符号不再用旧形状表(`markerSvg(shape)` 的三角形/圆形图标已废弃), // 与标记/设备一样走自绘水滴母版;domain 的 `markerSvg` 导入随之移除。 // 票 45:特效随标记 DOM 化 —— 周期/层数/放大倍数与 billboard 特效同一份 domain 常量(节奏单源)。 // 票 70(重做):本行导入的每一枚都必须有消费者(不留死导入,票面 Acceptance 第 3 条)。 import { DEVICE_EFFECT, effectProfileFor, RING_PERIOD_MS, GLOW_PERIOD_MS, EFFECT_PERIOD_MS } from '../domain/deviceEffects.js' // 票 76(2026-10-26):设备点的色键取设备状态词条(domain 单源),DOM 不自己映射状态→颜色。 import { deviceVisualForStatus } from '../domain/deviceStatus.js' /** * 类名单源:注入的特效 CSS(下方模板串)与 DOM 构建(buildNode/mount)共用同一组常量。 * 必须声明在 `FX_CSS` 之前——模板串在模块求值期就要读这些值(`const` 有 TDZ)。 * 前三枚为票 47 既有值(原样保留,勿改:走查断言与样式钩子读这些类名)。 */ const OVERLAY_HOST_CLASS = 'marker-overlay-host' const NODE_CLASS = 'marker-overlay-node' const LABEL_CLASS = 'marker-overlay-label' const FX_CLASS = 'marker-overlay-fx' const FX_RING_CLASS = 'marker-overlay-fx-ring' const FX_GLOW_CLASS = 'marker-overlay-fx-glow' /** * 特效层样式(票 45):keyframes 无法用行内 cssText 表达,所以注入一次