Skip to content

Commit ff67320

Browse files
committed
fix(3d): 移除晨曦穹顶场景重复的行星系统,导航行星统一由 SpatialNav 渲染
背景场景 AuroraDomeWorld 内置的 PlanetarySystem 与导航层 SpatialNav 渲染了两套重叠的可点击行星,外层行星点击只改状态不跳转,导致浅色模式下点击 3D 物体与功能错位。现将 AuroraDomeWorld 还原为纯环境背景,导航行星统一由 SpatialNav 提供。
1 parent a5d8f3b commit ff67320

2 files changed

Lines changed: 68 additions & 49 deletions

File tree

‎client/src/lib/3d/scenes/AuroraDomeWorld.tsx‎

Lines changed: 4 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
/**
22
* AuroraDomeWorld — 浅色模式「晨曦穹顶」3D场景
3-
* 天文馆般的穹顶世界:太阳系行星轨道 + 星尘粒子 + 云层
3+
* 天文馆般的穹顶世界:太阳 + 星尘粒子 + 云层(模块行星由 SpatialNav 统一渲染)
44
*
55
* @ai-context: 3D 场景:AuroraDomeWorld。
66
*/
77
import { useRef, useMemo } from 'react';
88
import { useFrame } from '@react-three/fiber';
99
import * as THREE from 'three';
10-
import { Float } from '@react-three/drei';
1110
import { Bloom, Vignette, ChromaticAberration } from '@react-three/postprocessing';
1211
import { BlendFunction } from 'postprocessing';
1312
import { SafeEffectComposer } from '../core/SafeEffectComposer';
1413
import { usePerformanceStore } from '../core/PerformanceMonitor';
15-
import { AuroraModuleEntity } from '../objects/AuroraModuleEntity';
16-
import { useOrbitalStore } from '../navigation/OrbitalStore';
17-
import type { ModuleId } from '../navigation/OrbitalStore';
1814

1915
// ─── 天空穹顶着色器 ───────────────────────────────────────
2016
const domeVertexShader = /* glsl */ `
@@ -267,47 +263,9 @@ function CloudLayer() {
267263
}
268264

269265
// ─── 行星轨道系统 ─────────────────────────────────────────
270-
const ORBIT_CONFIGS: Array<{
271-
id: ModuleId;
272-
radius: number;
273-
speed: number;
274-
initialAngle: number;
275-
}> = [
276-
{ id: 'dashboard', radius: 5, speed: 0.3, initialAngle: 0 },
277-
{ id: 'pomodoro', radius: 8, speed: 0.22, initialAngle: Math.PI * 0.33 },
278-
{ id: 'notes', radius: 11, speed: 0.16, initialAngle: Math.PI * 0.77 },
279-
{ id: 'flashcards', radius: 14, speed: 0.12, initialAngle: Math.PI * 1.2 },
280-
{ id: 'feynman', radius: 17, speed: 0.09, initialAngle: Math.PI * 1.6 },
281-
{ id: 'inspiration', radius: 20, speed: 0.06, initialAngle: Math.PI * 0.1 },
282-
];
283-
284-
function PlanetarySystem() {
285-
const { enterModule, setHovered } = useOrbitalStore();
286-
287-
const handleClick = (id: ModuleId) => {
288-
enterModule(id);
289-
};
290-
291-
const handleHover = (id: ModuleId | null) => {
292-
setHovered(id);
293-
};
294-
295-
return (
296-
<group>
297-
{ORBIT_CONFIGS.map((orbit) => (
298-
<AuroraModuleEntity
299-
key={orbit.id}
300-
id={orbit.id}
301-
orbitRadius={orbit.radius}
302-
orbitSpeed={orbit.speed}
303-
initialAngle={orbit.initialAngle}
304-
onClick={handleClick}
305-
onHover={handleHover}
306-
/>
307-
))}
308-
</group>
309-
);
310-
}
266+
// 模块行星(可点击导航)统一由 SpatialNav 渲染并负责路由跳转。
267+
// 本场景仅作环境背景,不重复生成行星实体——否则会出现两套可点击
268+
// 行星,外层行星只改状态不跳转,导致“点击 3D 物体”与功能错位。
311269

312270
// ─── 主场景组件 ───────────────────────────────────────────
313271
export function AuroraDomeWorld() {
@@ -333,9 +291,6 @@ export function AuroraDomeWorld() {
333291
{/* 太阳系统 */}
334292
<SunSystem />
335293

336-
{/* 行星轨道系统 */}
337-
<PlanetarySystem />
338-
339294
{/* 星尘粒子 */}
340295
<StarDust count={particleCount} />
341296

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# 知识卡片 · 踩坑记录
2+
3+
## 基本信息
4+
5+
| 字段 | 内容 |
6+
|------|------|
7+
| 标题 | 首页 3D 物体点击与功能错位:浅色模式下背景场景重复渲染了一套"只改状态不跳转"的行星 |
8+
| 日期 | 2026-08-01 |
9+
| 类型 | 踩坑记录 |
10+
| 标签 | #3D导航 #react-three-fiber #职责边界 #单一数据源 #浅色模式 |
11+
12+
---
13+
14+
## 症状
15+
16+
内测反馈:**首页的 3D 物体无法对应到其功能,与下方"点击 3D 物体进入模块"的提示有差异。**
17+
18+
具体表现(仅浅色模式必现):场景中可见一大一小两套行星;点击外层行星时,界面进入"模块态"遮罩,但页面内容仍是首页,没有跳转到对应功能页。
19+
20+
## 环境
21+
22+
| 项目 | 版本/信息 |
23+
|------|----------|
24+
| 主题 | 浅色模式(`data-theme` 非 `dark` → `aurora-dome` 场景) |
25+
| 相关文件 | `client/src/lib/3d/scenes/AuroraDomeWorld.tsx`、`client/src/lib/3d/navigation/SpatialNav.tsx`、`client/src/lib/3d/navigation/OrbitalStore.ts` |
26+
27+
## 排查过程(按 debug-sop)
28+
29+
1. **分类**:逻辑错误(运行正常但行为不对),无报错。
30+
2. **梳理渲染链路**:`AppLayout` → `SceneProvider` → `SceneTransition`(背景世界)+ `SpatialNav`(导航层)。
31+
3. **隔离**:发现浅色模式下有**两套**可点击行星同时渲染——
32+
- `AuroraDomeWorld` 内置 `PlanetarySystem`:6 颗行星(轨道半径 5~20,且缺 `classroom`),点击回调**只调用 `enterModule(id)`(改 Zustand 状态),不调用 `navigate()`**。
33+
- `SpatialNav`:7 颗 `AuroraModuleEntity`(轨道半径 0~9),点击回调 `enterModule(id)` + `navigate(module.route)`,才是唯一正确的导航出口。
34+
4. **对照深色模式**:`DeepSeaWorld` 是纯环境背景(光照 + 球体 + 后处理),不含任何模块实体,只有 `SpatialNav` 一套可点击对象——所以深色模式正常。由此锁定问题在 `AuroraDomeWorld` 多出的那套行星。
35+
5. **推演点击外层行星的后果**:`enterModule` 把 `isInModule` 置真 → `AppLayout` 渲染 `FunctionalOverlay` + `<Outlet/>`,但路由未变,`Outlet` 仍渲染当前页(首页)→ 用户看到"进了模块但内容没变"的错位。
36+
37+
## 根因
38+
39+
**背景场景越界实现了导航职责,产生第二套可点击实体。** `AuroraDomeWorld` 作为环境背景,自带了一个 `PlanetarySystem`,其点击处理只改状态不跳转;它与 `SpatialNav` 的导航行星在 3D 空间重叠,用户点到外层行星即触发"进入模块态但不跳转"。这也违反了 `OrbitalStore` 注释中"MODULE_POSITIONS 与路由映射需与 routes 配置同步"的单一数据源约定。
40+
41+
## 修复方案
42+
43+
将 `AuroraDomeWorld` 还原为纯环境背景(对齐 `DeepSeaWorld` 的职责边界),可点击导航行星统一由 `SpatialNav` 提供:
44+
45+
1. 删除 `AuroraDomeWorld` 中的 `ORBIT_CONFIGS` 与 `PlanetarySystem`,以及 JSX 里的 `<PlanetarySystem />`。
46+
2. 清理随之失效的导入:`AuroraModuleEntity`、`useOrbitalStore`、`ModuleId`,并顺带移除预先存在的未使用导入 `Float`。
47+
3. 在原 `行星轨道系统` 分节处保留注释,说明"模块行星统一由 SpatialNav 渲染",防止后人再次在此重复造行星。
48+
49+
```
50+
// 模块行星(可点击导航)统一由 SpatialNav 渲染并负责路由跳转。
51+
// 本场景仅作环境背景,不重复生成行星实体——否则会出现两套可点击
52+
// 行星,外层行星只改状态不跳转,导致"点击 3D 物体"与功能错位。
53+
```
54+
55+
## 教训
56+
57+
- **3D 场景里"背景"与"导航"职责必须分离**:背景世界(`DeepSeaWorld`/`AuroraDomeWorld`)只做环境渲染;一切可点击导航实体只能来自 `SpatialNav`。新增场景时对照 `DeepSeaWorld` 的纯净结构。
58+
- **同一交互对象出现两套实例是高危信号**:两套行星轨道半径不同(0~9 vs 5~20)、数量不同(7 vs 6,缺 classroom)、回调行为不同,任何一处差异都会变成用户可感知的错位。
59+
- **"只改状态不跳转"的点击回调是隐蔽 bug**:`enterModule` 不报错、UI 也有遮罩反馈,表面"有响应",实则路由未变。排查"点了没到预期页面"时,先确认点击回调里是否真的调用了 `navigate`。
60+
- 排查此类问题的高效方法:**沿渲染链路列出所有同类可点击实体,逐个核对其点击回调**,而不是只看其中一个。
61+
62+
## 相关提交
63+
64+
- fix(3d): 移除晨曦穹顶场景中重复的行星系统,导航行星统一由 SpatialNav 渲染(待提交)

0 commit comments

Comments
 (0)