fix: polish earth toolbar controls and loading copy

This commit is contained in:
linkong
2026-03-26 14:04:57 +08:00
parent 7b53cf9a06
commit ab09f0ba78
8 changed files with 239 additions and 19 deletions

View File

@@ -1 +1 @@
0.21.0
0.21.1

View File

@@ -47,6 +47,27 @@ Released: 2026-03-26
- Older satellite records can still fall back to backend-generated TLE lines when raw lines are unavailable.
- This release is primarily focused on Earth module stability rather than visible admin UI changes.
## 0.21.1
Released: 2026-03-26
### Highlights
- Refined the Earth big-screen toolbar with clearer controls, hover hints, and more consistent visual language.
- Replaced emoji-based Earth toolbar controls with SVG icons for a cleaner HUD.
- Updated the Earth loading splash so manual reloads no longer show legacy wording.
### Improved
- Improved zoom controls by adding tooltips for reset view, zoom in, zoom out, and resetting zoom to `100%`.
- Improved Earth toolbar readability with larger icons and revised glyphs for rotation, reload, satellites, trails, cables, terrain, and collapse.
- Improved loading overlay copy to better distinguish initial initialization from manual refresh.
### Fixed
- Fixed rotate toggle rendering so play/pause state no longer relies on emoji text replacement.
- Fixed Earth autorotation target syncing so inertial drag is preserved while the globe is still coasting.
## 0.21.0
Released: 2026-03-26

View File

@@ -16,7 +16,7 @@
## Current Version
- `main` 当前主线历史推导到:`0.16.5`
- `dev` 当前开发分支历史推导到:`0.21.0`
- `dev` 当前开发分支历史推导到:`0.21.1`
## Timeline
@@ -63,6 +63,7 @@
| `0.19.0` | feature | `dev` | `020c1d50` | refine data management and collection workflows |
| `0.20.0` | feature | `dev` | `ce5feba3` | stabilize Earth module and fix satellite TLE handling |
| `0.21.0` | feature | `dev` | `pending` | add Earth inertial drag, sync hover/trail state, and support unlimited satellite loading |
| `0.21.1` | bugfix | `dev` | `pending` | polish Earth toolbar controls, icons, and loading copy |
## Maintenance Commits Not Counted as Version Bumps

View File

@@ -65,6 +65,7 @@ body {
font-weight: 600;
color: #4db8ff;
min-width: 30px;
display: inline-block;
text-align: center;
cursor: pointer;
padding: 2px 4px;
@@ -96,6 +97,7 @@ body {
margin: 0;
flex: 0 0 auto;
box-sizing: border-box;
position: relative;
}
#zoom-toolbar .zoom-btn:hover {
@@ -104,6 +106,55 @@ body {
box-shadow: 0 0 10px rgba(77, 184, 255, 0.5);
}
#zoom-toolbar #reset-view svg {
width: 18px;
height: 18px;
stroke: currentColor;
stroke-width: 1.8;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
}
#zoom-toolbar .zoom-percent {
position: relative;
}
#zoom-toolbar .tooltip {
position: absolute;
right: calc(100% + 10px);
top: 50%;
transform: translateY(-50%);
background: rgba(10, 10, 30, 0.95);
color: #fff;
padding: 6px 12px;
border-radius: 6px;
font-size: 12px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: all 0.2s ease;
border: 1px solid rgba(77, 184, 255, 0.4);
pointer-events: none;
z-index: 100;
}
#zoom-toolbar .zoom-btn:hover .tooltip,
#zoom-toolbar .zoom-percent:hover .tooltip {
opacity: 1;
visibility: visible;
}
#zoom-toolbar .tooltip::after {
content: '';
position: absolute;
left: 100%;
top: 50%;
transform: translateY(-50%);
border: 6px solid transparent;
border-left-color: rgba(77, 184, 255, 0.4);
}
#loading {
position: absolute;
top: 50%;
@@ -264,11 +315,23 @@ input[type="range"]::-webkit-slider-thumb {
}
.toggle-arrow {
font-size: 14px;
display: inline-flex;
align-items: center;
justify-content: center;
color: #4db8ff;
transition: transform 0.3s ease;
}
.toggle-arrow svg {
width: 16px;
height: 16px;
stroke: currentColor;
stroke-width: 2.2;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
}
#control-toolbar.collapsed .toggle-arrow {
transform: rotate(0deg);
}
@@ -328,6 +391,31 @@ input[type="range"]::-webkit-slider-thumb {
box-shadow: 0 0 10px rgba(77, 184, 255, 0.4) inset;
}
.toolbar-btn .icon {
display: inline-flex;
align-items: center;
justify-content: center;
}
.toolbar-btn svg {
width: 18px;
height: 18px;
stroke: currentColor;
stroke-width: 2.1;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
}
#rotate-toggle .icon-play,
#rotate-toggle.is-stopped .icon-pause {
display: none;
}
#rotate-toggle.is-stopped .icon-play {
display: inline-flex;
}
.toolbar-btn .tooltip {
position: absolute;
bottom: 50px;

View File

@@ -38,22 +38,104 @@
<div id="right-toolbar-group">
<div id="zoom-toolbar">
<button id="reset-view" class="zoom-btn">🎯</button>
<button id="zoom-in" class="zoom-btn">+</button>
<span id="zoom-value" class="zoom-percent">100%</span>
<button id="zoom-out" class="zoom-btn"></button>
<button id="reset-view" class="zoom-btn" title="重置视角">
<svg viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="5"></circle>
<path d="M12 3v4"></path>
<path d="M12 17v4"></path>
<path d="M3 12h4"></path>
<path d="M17 12h4"></path>
<circle cx="12" cy="12" r="1.5" fill="currentColor" stroke="none"></circle>
</svg>
<span class="tooltip">重置视角</span>
</button>
<button id="zoom-in" class="zoom-btn" title="放大">+<span class="tooltip">放大</span></button>
<span id="zoom-value" class="zoom-percent" title="重置缩放到100%">100%<span class="tooltip">重置缩放到100%</span></span>
<button id="zoom-out" class="zoom-btn" title="缩小"><span class="tooltip">缩小</span></button>
</div>
<div id="control-toolbar">
<div class="toolbar-items">
<button id="rotate-toggle" class="toolbar-btn" title="自动旋转">🔄<span class="tooltip">自动旋转</span></button>
<button id="toggle-cables" class="toolbar-btn active" title="显示/隐藏线缆">🌐<span class="tooltip">隐藏线缆</span></button>
<button id="toggle-terrain" class="toolbar-btn" title="显示/隐藏地形">⛰️<span class="tooltip">显示/隐藏地形</span></button>
<button id="toggle-satellites" class="toolbar-btn" title="显示/隐藏卫星">🛰️<span class="tooltip">显示卫星</span></button>
<button id="toggle-trails" class="toolbar-btn active" title="显示/隐藏轨迹"><span class="tooltip">隐藏轨迹</span></button>
<button id="reload-data" class="toolbar-btn" title="重新加载数据">🔃<span class="tooltip">重新加载数据</span></button>
<button id="rotate-toggle" class="toolbar-btn" title="自动旋转">
<span class="icon rotate-icon icon-pause" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path d="M9 6v12"></path>
<path d="M15 6v12"></path>
</svg>
</span>
<span class="icon rotate-icon icon-play" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path d="M8 6.5v11l9-5.5z" fill="currentColor" stroke="none"></path>
</svg>
</span>
<span class="tooltip">自动旋转</span>
</button>
<button id="toggle-cables" class="toolbar-btn active" title="显示/隐藏线缆">
<span class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<circle cx="12" cy="12" r="6.5"></circle>
<path d="M5.8 12h12.4"></path>
<path d="M12 5.8a8.5 8.5 0 0 1 0 12.4"></path>
<path d="M8 16c2-1.8 6-1.8 8 0"></path>
</svg>
</span>
<span class="tooltip">隐藏线缆</span>
</button>
<button id="toggle-terrain" class="toolbar-btn" title="显示/隐藏地形">
<span class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path d="M3 18h18"></path>
<path d="M4.5 18l5-7 3 4 3.5-6 3.5 9"></path>
<path d="M11 18l2-3 1.5 2"></path>
</svg>
</span>
<span class="tooltip">显示/隐藏地形</span>
</button>
<button id="toggle-satellites" class="toolbar-btn" title="显示/隐藏卫星">
<span class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<rect x="10" y="10" width="4" height="4" rx="0.8"></rect>
<rect x="4" y="9" width="4" height="6" rx="0.8"></rect>
<rect x="16" y="9" width="4" height="6" rx="0.8"></rect>
<path d="M8 12h2"></path>
<path d="M14 12h2"></path>
<path d="M12 8V6"></path>
<path d="M11 6h2"></path>
<path d="M12 14v4"></path>
<path d="M10 18h4"></path>
</svg>
</span>
<span class="tooltip">显示卫星</span>
</button>
<button id="toggle-trails" class="toolbar-btn active" title="显示/隐藏轨迹">
<span class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path d="M5 17h7"></path>
<path d="M7 13.5h8"></path>
<path d="M10 10h6"></path>
<circle cx="17.5" cy="8.5" r="2.2" fill="currentColor" stroke="none"></circle>
<path d="M15.8 10.2l2.8-2.8"></path>
</svg>
</span>
<span class="tooltip">隐藏轨迹</span>
</button>
<button id="reload-data" class="toolbar-btn" title="重新加载数据">
<span class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path d="M20 5v5h-5"></path>
<path d="M20 10a8 8 0 1 0 2 5"></path>
</svg>
</span>
<span class="tooltip">重新加载数据</span>
</button>
</div>
<button id="toolbar-toggle" class="toolbar-btn" title="展开/收起工具栏"><span class="toggle-arrow"></span></button>
<button id="toolbar-toggle" class="toolbar-btn" title="展开/收起工具栏">
<span class="toggle-arrow" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path d="M15 6l-6 6 6 6"></path>
</svg>
</span>
</button>
</div>
</div>
@@ -125,8 +207,8 @@
<div id="loading">
<div id="loading-spinner"></div>
<div>正在加载3D地球和电缆数据...</div>
<div style="font-size:0.9rem; margin-top:10px; color:#aaa;">使用8K高分辨率卫星纹理 | 大陆轮廓更清晰</div>
<div id="loading-title">正在初始化全球态势数据...</div>
<div id="loading-subtitle" style="font-size:0.9rem; margin-top:10px; color:#aaa;">同步卫星、海底光缆与登陆点数据</div>
</div>
<div id="status-message" class="status-message" style="display: none;"></div>
<div id="tooltip" class="tooltip"></div>

View File

@@ -371,7 +371,7 @@ function updateRotateUI() {
const btn = document.getElementById("rotate-toggle");
if (btn) {
btn.classList.toggle("active", autoRotate);
btn.innerHTML = autoRotate ? "⏸️" : "▶️";
btn.classList.toggle("is-stopped", !autoRotate);
const tooltip = btn.querySelector(".tooltip");
if (tooltip) tooltip.textContent = autoRotate ? "暂停旋转" : "开始旋转";
}

View File

@@ -9,6 +9,7 @@ import {
updateZoomDisplay,
updateEarthStats,
setLoading,
setLoadingMessage,
showTooltip,
hideTooltip,
showError,
@@ -392,6 +393,12 @@ async function loadData(showWhiteSphere = false) {
const loadToken = ++currentLoadToken;
isDataLoading = true;
hideError();
setLoadingMessage(
showWhiteSphere ? "正在刷新全球态势数据..." : "正在初始化全球态势数据...",
showWhiteSphere
? "重新同步卫星、海底光缆与登陆点数据"
: "同步卫星、海底光缆与登陆点数据",
);
setLoading(true);
clearLockedObject();
hideInfoCard();
@@ -761,12 +768,20 @@ function animate() {
const earth = getEarth();
const deltaTime = clock.getDelta() * 1000;
const hasInertia =
Math.abs(inertialVelocity.x) > INERTIA_MIN_VELOCITY ||
Math.abs(inertialVelocity.y) > INERTIA_MIN_VELOCITY;
if (getAutoRotate() && earth) {
earth.rotation.y += CONFIG.rotationSpeed * (deltaTime / 16);
// Keep the drag target aligned with autorotation only when the user is not
// actively dragging and there is no residual inertial motion to preserve.
if (!isDragging && !hasInertia) {
targetRotation.y = earth.rotation.y;
targetRotation.x = earth.rotation.x;
}
}
if (earth) {
if (isDragging) {

View File

@@ -73,6 +73,19 @@ export function setLoading(loading) {
loadingEl.style.display = loading ? "block" : "none";
}
export function setLoadingMessage(title, subtitle = "") {
const titleEl = document.getElementById("loading-title");
const subtitleEl = document.getElementById("loading-subtitle");
if (titleEl) {
titleEl.textContent = title;
}
if (subtitleEl) {
subtitleEl.textContent = subtitle;
}
}
// Show tooltip
export function showTooltip(x, y, content) {
const tooltip = document.getElementById("tooltip");