fix: polish earth toolbar controls and loading copy
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
2
frontend/public/earth/js/controls.js
vendored
2
frontend/public/earth/js/controls.js
vendored
@@ -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 ? "暂停旋转" : "开始旋转";
|
||||
}
|
||||
|
||||
@@ -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,11 +768,19 @@ 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);
|
||||
targetRotation.y = earth.rotation.y;
|
||||
targetRotation.x = earth.rotation.x;
|
||||
|
||||
// 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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user