04-panel-anchor-following-form.md 14 KB

监测面板锚定跟随的形态与退化策略

Type: grilling Status: resolved Labels: wayfinder:grilling Blocked by: None

进度:100%

维护者已确认完整结论,五轮讨论覆盖目标、边界、风险、选项权衡与决策;结论见 ## Answer,本票收口。后续 /to-spec 已将本票结论固化为同一张 map 的 12: 锚定跟随规格,可供后续实施;同图 05/06/07/08 继续消费本票锚定契约。

2026-09-24 原位修订(走查后):维护者改变遮挡规范主意,## Answer 顶部新增修订节 R-1~R-4,取代原文的「避让左右栏/图例/底部」与「被遮住或放不下则暂隐」,并改定层级低于四个详情窗、可被遮盖、只在完全离开画面时隐藏。原文保留以追溯;实现以修订节为准。规格 12 已同步。

下一步:按子票 12 规格(含修订节)实施并核验 1080p/4K 手感;本票保留已收口状态。

Question

需求③原句:「弹出的监测面板应跟随监测点位置移动,表明该面板所属的监测点位」——面板必须看得出它属于哪个点位。

现状(本图 map.md 事实 4):components/PointDetailCard.vue 是浮在左右两栏之间的固定浮层(CockpitShell.vue 里 main 内地图与两栏的兄弟),不读屏幕坐标;左右两栏 z-index:2 压在满幅地图上(票 07 记录的定位约束);一张图顶部还有图例与抬头(票 33)、底部有摘要行与引擎状态小字(票 32)。

请裁决:

  1. 「跟随」的形态三选一或组合:(a) 世界坐标锚定 —— 把点位投到屏幕、面板贴着它显示;(b) 屏幕固定 + 归属指示 —— 面板仍在固定位,另加引线/标签指向点位;(c) 折中(近处锚定、远处或出界时回固定位)。选哪个,理由是什么(可读性 / 遮挡 / 手感)。
  2. 投影口径:用 SceneTransforms.worldToWindowCoordinates 还是 camera 手算?锚点是点位地表点还是标记顶部(票 10 的走查实测:贴地标记与「高度 0 的中心」相差约 30px 的地形高程差);z 在相机背面/地平线以下时怎么判(Cartesian4.w 或投影后判断)。
  3. 避让与翻转:与左右两栏、顶部图例、底部摘要行与引擎状态行的避让规则;四个方向翻转的判据(可用几何表述,例如「面板矩形与栏矩形相交即翻转」);面板最大尺寸与滚动上限。
  4. 退化:点位在屏外、被 3D Tiles 体块遮挡、或相机飞行途中时,分别贴边 / 隐藏 / 回固定位哪一种?飞行途中是否实时跟随(每帧投影的帧率成本,是否需要节流)。
  5. 改动边界:这是纯表现层(components/PointDetailCard.vue + 少量服务层投影查询),还是要动 domain/detailFlow.js 的层级与 stores/detailStore.js 的选择语义?写明结论,避免实现票自由发挥。
  6. 与关闭/取消选中的对齐:关闭面板后锚点保留还是收回?与票 04「取消选中不回退中心」是否同一套语义。

Answer

⚠ 2026-09-24 原位修订(本节优先于下方原文)

维护者在票 08 走查后对遮挡规范改主意,以下条款取代原文对应条款。原文保留不删以便追溯;凡冲突,以本节为准。

R-1(取代「避让业务栏/图例/底部摘要」与「被 UI 遮住则暂隐」):浮动面板不再把左右业务栏、顶部图例、底部摘要行、无地图位置浮块当作避让矩形,也不再因为标记落入这些区域而暂隐(原文第三轮 Q12=A 作废)。面板只避开画布边缘。

R-2(取代「四周都放不下则暂隐」):取消 no-space 暂隐。面板允许被屏幕裁切(可能出现只剩一半的情况),不再为「放不下」而整体消失。

R-3(层级):浮动面板的层级低于左右两侧的四个详情窗(在 --z-columns 之下),因此允许被它们遮盖。维护者先前提过「在详情窗之上」,随后明确更正为「让浮动窗口层级比详情窗口低就好,这意味着浮动窗口能够被两边的四个详情窗遮盖」——以更正后的说法为准。

R-4(唯一的隐藏条件):只有窗口完全离开画面时才隐藏。这是 R-2 的用意:避免「移动到某个会被详情窗遮住的位置时突然消失」这种突兀行为——被遮住是允许的,消失不是。

仍然不变(本节不动它们):始终贴可见标记、四向顺序、不压图标、卡片内滚动、暂隐保留两级选择与顶栏退出、无地图位置特例、关闭不回退镜头、投影口径与可见性以视觉标记为准。

修订理由与代价(如实记录):新规范与参考图一致(信息卡与场景的关系),代价是极端拥挤时面板会被裁切或被侧栏盖住;维护者已明确接受该代价。no-space / icon-covered 两个暂隐原因不再触发,实现时应移除或标为废弃,避免留死代码。

连带影响:本票的派生规格 12 已同步修订;票 08 原型的控制台仍按老规范做(原型只记约束、不再改),实现以本节为准。

目标与边界

  • 打开某监测点的两级详情时,面板始终贴着该监测点的视觉标记中心随画面移动,清楚表达归属;进入设备级详情仍指向所属监测点。地图上的未关联设备没有上级监测点,打开其设备详情时锚向自身的有效地图标记。
  • 面板不得盖住图标。业务对象确属无地图位置时仍可从台账打开注明原因的固定详情,这是没有有效地图锚点时的特例,不伪造标记或跟随关系;无有效坐标的设备也不上图。
  • 关闭详情时收起卡片、短线和面板专属指示,清除详情选择;镜头与旋转中心依 ADR 0008 留在当前视角,不因关闭而回退。点位级与设备级导航、取数语义不变。

风险与选项权衡

  • 维护者选择始终贴点,以明确归属;固定面板加引线或近远切换到固定位置不满足这一形态。长清单与业务栏争空间时,依右→左→下→上尝试贴点翻转,缩到可读下限并在卡内滚动;仍放不下则暂隐,不回固定位。
  • 现有监测点标记贴地、18×18 CSS px 且中心对齐,忽略深度遮挡;椭球高度 0 的经纬度投影会偏离视觉标记。以贴地后的视觉标记中心为锚,卡片边缘距图标外缘至少 12 CSS px,细短线接至图标外缘,不能压住图标。3D Tiles 挡住地表而图标仍看得见时,卡片继续跟随图标;不另按地表遮挡结果让它消失。
  • 标记离屏、在相机背后或地平线后、被业务 UI 覆盖、投影无效、或四向都放不下面板时,暂时隐藏面板,保留选择、设备层级和已取详情;可见且空间恢复后自动重现。不沿用上帧旧位置,不因经过屏外而关闭或重取数据。
  • 暂隐时顶栏留简短状态入口,显示当前对象名称或编码及暂隐原因,提供关闭;只有仍有有效标记时才提供重新定位。换快照后按编码重新关联有效标记;新快照尚未查完或查找失败时保留选择与关闭入口,不持有旧 Cesium 实体。后续票 05 已裁定:同一新快照完整加载仍无该点时关闭详情并说明原因。

投影、避让与性能决策

  • 使用 Cesium 世界坐标到画布坐标投影,换算成窗口坐标;显式校验贴地标记位置、相机前方与地球背面/地平线、画布边界和盖住图标的 UI。投影空值、非有限值或无效位置直接暂隐,不另写相机矩阵手算投影。可见性与用户实际看到的标记一致;3D Tiles 遮住地表不等于视觉标记不可见。
  • 左右业务栏、顶部图例和调试抬头、底部摘要与引擎状态,以及“无地图位置”浮块,都作为避让矩形。候选卡片必须在地图画布可用区域内,不与这些矩形或图标相交;按右、左、下、上尝试,画布边缘留约 12 CSS px;侧边可沿垂直方向滑动但连线仍指向同一图标。使用运行时实际矩形交集判定。
  • 面板宽 300–420 CSS px;高度上限为扣除避让区后的地图画布可用屏幕高度的 80%,也不能超过候选矩形的实际可用高度。可用高度低于约 280 CSS px 时暂隐;标题和关闭入口固定在卡内,长设备卡片/设备详情正文在卡内滚动。“可用屏幕高度”不指 CONTEXT.md 定义的地理主场景区。
  • 定位飞行、轨道旋转、滚轮与平移期间,卡片连续跟随可见图标。只为当前一处锚点随画面已渲染帧投影与布局,每帧最多一次;无详情、页面不可见或相机稳定且布局未变化时停止,恢复或尺寸变化后立即重算。4K 帧耗与手感交给后续实现走查核验。
  • 以当前地图对象的编码取得有效标记;引擎服务提供只读的贴地标记位置、投影与可见性查询,组件持有暂时可见/落位状态。不改 domain/detailFlow.js 的两级导航、detailStore.js 的 {level, pointCode, deviceCode} 选择语义,不把每帧坐标塞进业务 store。当前仅有开发态 projectPivot,地图点选也还未兑现本图票 03 的定位预设;后续实现接线应服从该票已锁的真实地形与完整视角预设,不以旧代码的高度 0、只换中心行为作为目标。

验收与后续

  • 走查飞行和手动移动中的贴合且不盖图标;标记离屏/被 UI 遮住时暂隐、顶栏可关闭、重入自动恢复原详情;四向翻转、滚动与无空间暂隐;侧视地表被体块挡住但图标仍见时继续跟随;换快照后按同编码重关联、查找未完成或失败时顶栏仍可退出;新快照完整确认不存在时依票 05 关闭详情。无地图位置与未关联设备各守其例外。
  • 本票只锁监测点详情面板锚定跟随;设备点位展开、设备与三维点位联动、状态特效分别归本图 05/06/07,视觉/手感原型归 08。若 1080p/4K 实测表明 300×280 CSS px 下限或帧性能不合适,回本票重议数值,不让实现票自行改掉“贴点 / 暂隐”的优先级。

Comments

第一轮:目标与边界(已收到选择,待最终确认)

已锁目标:点位选择后定位到点位视角(本图票 03,当前代码尚未接线);关闭详情不回退镜头(ADR 0008);详情浮层目前位于一张图与左右栏之间的固定区域,不读取点位屏幕坐标。

维护者选择:Q1=A(面板始终贴点移动);Q2=两级都指向所属监测点(未关联设备没有虚构的监测点锚);Q3=详情随不可见点位隐藏;Q4=关闭时面板专属的归属指示收回,镜头按既有契约不回退。第一轮选择仍需下游边界细化,不将本轮选择当作最终结论。

第二轮:隐藏、空间、飞行与特殊入口(已收到选择,待最终确认)

维护者选择:Q5=A(临时隐藏;保留当前点位/设备层级与已取数据,点位重入视野时自动重现);Q6=B(四周不足时缩至可读下限、内部滚动,仍放不下则隐藏,不回固定位);Q7=A(飞行和手动移动期间连续跟随);Q8=A(无地图位置的监测点仍可从台账打开注明原因的固定详情,属于无锚点特例);Q9=A(地图上的未关联设备以自身标记为锚,不虚构所属监测点)。

只读核实:当前标记 HeightReference.CLAMP_TO_GROUND、中心锚点且 disableDepthTestDistance: Infinity,不能直接把“地表被体块挡住”推作“标记不可见”;投影当前仅有 worldToWindowCoordinates 与画布原点换算,没有遮挡/背面有效性判据。现有地图点选路径仅开详情,尚未兑现本图票 03 的预设定位契约;本票讨论按已锁目标契约,现状差异留实现时解决。

第三轮:锚点、遮挡、避让与尺寸(已收到选择,待最终确认)

维护者选择:Q10=A,并特别要求贴视觉标记中心时不能遮住标记图标;Q11=A(可见性以用户实际看得到的标记为准,当前标记忽略 3D Tiles 深度遮挡,地表点被挡而标记可见时继续显示面板);Q12=A(标记落入业务栏或图例遮挡区时暂时隐藏、保留选择);Q13=同意依次右、左、下、上尝试,按实际矩形避让左右栏、顶部图例/标题、底部摘要/引擎状态及“无地图位置”块;Q14=认可宽 300–420 CSS px、高不超过主场景区可用高度 80%、约 280 CSS px 高度下限,长内容在卡内滚动。间距、无效投影、帧率与数据边界已进入第四轮。

第四轮:连接线、投影、性能与状态边界(已收到选择,待最终确认)

维护者选择:Q15=图标外缘与卡片至少 12 CSS px 间距,画细短线到图标外缘,不遮盖图标;Q16=沿用 Cesium 世界坐标投影,并显式校验前方/地平线后、屏内和 UI 遮挡,投影缺失/无效即临时隐藏,不沿用旧位置;Q17=仅对当前一锚点随画面帧更新,一帧至多一次,没有详情/页面不可见/镜头稳定且布局未变化时停算,恢复后重算;Q18=沿编码从当前地图对象/实际标记取锚点,投影与布局归表现层,不改 domain/detailFlow.js 的两级导航状态和 detailStore.js 的选择语义;Q19=换快照暂失标记时暂时隐藏、选中保留,同编码重新出现后自动重现,即便标记永久从快照消失也保留选择;Q20=尺寸上限按地图画布扣除避让区后的可用屏幕高度表达,不把 CONTEXT.md 的地理“主场景区”当屏幕尺寸。

剩余风险已在第五轮裁定;当前 projectPivot 只提供窗口坐标且不够判断视觉标记的有效性,未来引擎适配需增加只读查询。

第五轮:暂隐后的退出路径(已收到选择,待最终确认)

维护者选择 Q21=A:暂隐时顶栏保留简短状态入口(对象名称或编码、暂隐原因和关闭动作);仍有有效标记时才提供重新定位,不向消失的标记发无效定位。该选择既保留 Q19 的隐藏选择,也避免卡片上的关闭按钮消失后无法退出。完整拟议结论随后在对话中供维护者核对;确认前 ## Answer 保持待填。

收口确认

维护者已明确选择“确认,按此收口”。据此将五轮结论写入 ## Answer,本票改为 Status: resolved、进度 100%。