7.4 KiB
7.4 KiB
Earth 工具栏与浮层协同
本文件描述 Earth 大屏右侧工具栏按钮,以及搜索面板、设置弹窗、新闻直播面板、图层面板这几个浮层之间当前的协同规则。改交互、加按钮、调整面板时按这个表对齐,避免出现「点 A 把不该关的 B 也关了」之类的协同冲突。
相关入口:
工具栏按钮目录
工具栏在 index.html 中以 .earth-toolbar-btn 标识,按钮列表:
| ID | 标题 | 类型 | 触发的浮层/动作 |
|---|---|---|---|
layer-action |
图层 | 浮层切换 | HUD 面板 layer-toggles(桌面)/ 移动端抽屉 layers 卡 |
search-action |
搜索 | 浮层切换 | 搜索面板(桌面)/ 移动端抽屉 search 卡 |
rotate-toggle |
自动旋转 | 独立开关 | 不打开任何浮层 |
toggle-tv |
新闻直播 | 浮层切换 | 媒体面板 media-panel(含 TV/News 两个 tab) |
reload-data |
重新加载数据 | 独立动作 | 不打开任何浮层 |
zoom-trigger |
缩放控制 | 浮动菜单 | 缩放 floating menu |
settings-trigger |
设置 | 浮层切换 | 设置弹窗(桌面)/ 移动端抽屉 settings 卡 |
reset-view |
重置视角 | 独立动作 | 不打开任何浮层 |
layout-toggle |
最大化布局 | 独立开关 | 不打开任何浮层 |
浮层协同的统一入口
controls.js::closeTransientMobileOverlays 是「打开 X 时该关谁」的统一协调函数。
调用约定:每个会进入 fullscreen-style 浮层的开启路径调用 closeTransientMobileOverlays({ except }),告诉协调函数「除了我这一类,其他互斥浮层一律关掉」。
closeTransientMobileOverlays({ except: "search" }); // 搜索打开
closeTransientMobileOverlays({ except: "settings" }); // 设置打开
closeTransientMobileOverlays({ except: "media" }); // 新闻直播打开
closeTransientMobileOverlays({ except: "layer-toggles" }); // 图层抽屉(移动端)
except 当前可取的值:"search"、"settings"、"media"、"layer-toggles",或省略表示「全部关闭」。
关闭矩阵
下表描述「打开 X」时其它浮层的命运。✓ = 关闭,— = 保留。
| 触发动作 → | 关搜索 | 关设置 | 关图层抽屉(移动端) | 关新闻/直播 |
|---|---|---|---|---|
打开搜索 (except: "search") |
(自身) | ✓ | ✓ | — |
打开设置 (except: "settings") |
✓ | (自身) | ✓ | — |
打开新闻/直播 (except: "media") |
✓ | ✓ | ✓ | (自身) |
打开图层抽屉 (except: "layer-toggles") |
✓ | ✓ | (自身) | ✓ |
全部关闭 (except: null) |
✓ | ✓ | ✓ | ✓ |
读法举例:
- 点工具栏「设置」,搜索面板和图层抽屉会被关掉,新闻/直播面板保持原状。
- 点工具栏「图层」(移动端打开
layers抽屉),搜索 / 设置 / 新闻 全关。 - 点工具栏「新闻直播」,搜索 / 设置 / 图层抽屉全关,新闻面板自身切换为打开。
设计原则
下面是当前矩阵背后的几条不变量。新增浮层或调整规则时按它们对齐:
zoom-trigger等浮动菜单不属于浮层。 它们走bindFloatingMenu,由closeFloatingMenus()单独管理;任何浮层打开都会先调一次closeFloatingMenus()。- 桌面
layer-toggles是常驻 HUD 面板,不是浮层。closeTransientMobileOverlays中只有activeMobileDrawerId === "layer-toggles"(移动端抽屉态)才会被关掉。所以桌面打开搜索/设置/新闻不会动图层面板,符合「桌面屏幕大、可共存」的预期。 - 新闻/直播面板独立于设置。 用户切到设置改采集器时,常常想边看新闻边改配置,所以打开设置时不关新闻面板。这条是 2026-05 的协同补丁后建立的不变量;改设置打开路径时不要再去主动关
media-panel。 - 搜索和新闻面板视为「主信息浮层」,互相独立。 搜索打开不关新闻、新闻打开不关搜索:两者面向不同任务(搜索定位 / 浏览态势新闻),允许同屏共存。如果未来 UX 上希望它们互斥,要在
closeTransientMobileOverlays中同时改两边的规则,避免单边修改导致非对称的关闭逻辑。 - 移动端抽屉是 fullscreen 级别的状态。 一旦进入移动端抽屉,无论是
layers/search/settings哪一类,都会通过setMobileDrawerState关闭其它浮层。这是 mobile 单一焦点 UX 的要求。 Escape键有固定的关闭顺序。 见 controls.js::setupKeyboardControls:搜索 → 设置 → 移动端抽屉 → 浮动菜单 → 工具栏 hub → 锁定对象。新增浮层要决定它在这个顺序中的位置。
新加按钮 / 浮层时怎么接
按下面的清单走,规则就不会乱:
- 按钮加在 index.html 的
.earth-toolbar容器里,class 跟齐floating-btn liquid-glass-surface earth-toolbar-btn。 - 决定它属于哪一类:
- 独立动作(reload / reset / rotate / layout):直接
bindListener,不调任何closeTransientMobileOverlays。 - 浮动菜单(zoom 这种 dropdown):用
bindFloatingMenu,不进协同矩阵。 - 互斥浮层:进矩阵。
- 独立动作(reload / reset / rotate / layout):直接
- 互斥浮层要做两件事:
- 在打开路径调用
closeTransientMobileOverlays({ except: "<your-key>" }),让其他浮层主动让位。 - 在
closeTransientMobileOverlays函数体内补一条if (except !== "<your-key>" && isYourPanelVisible()) closeYourPanel();让别的浮层打开时关掉自己。
- 在打开路径调用
- 如果新浮层和某个现有浮层(例如新闻面板)应当共存,参考第 3 条规则:在自己的关闭判断里
&& except !== "<peer-key>"把对方排除掉。不要只单边改一处,否则关闭逻辑会非对称。 - 新浮层应该有
Escape关闭路径,加在setupKeyboardControls中合适的位置。 - 移动端如果应进入抽屉态,使用
setMobileDrawerState({ open: true, card: "<your-card>" })而不是直接 toggle 面板。
当前实现位置
- 协调入口:controls.js::closeTransientMobileOverlays
- 设置浮层:controls.js::openSettingsModal / closeSettingsModal
- 搜索浮层:controls.js(导入自 search 模块)
- 新闻/直播浮层:tv.js::setTVPanelVisible、新闻 tab 在 news.js
- 图层抽屉(移动端):controls.js::setMobileDrawerState
- 浮动菜单:controls.js::bindFloatingMenu
- 工具栏 DOM:index.html