Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← 其他内容 / Other Topics

项目实践 / Projects

CWFrame 项目 / CWFrame Project

1. 计算机宇宙探索器 / Computer Universe Explorer

2. CWFrame v0.1 26/3/25 前端渲染逻辑总结 / CWFrame Frontend Rendering Architecture Review

3. 🛡️ Computer-WorldFrame 项目技术面试指南 / A Technical Interview Guide for the Computer-World Frame Project

项目经历 / Project Experience

C++ 项目 / C++ Projects

1. C++ 技能要求列表 / C++ Skills and Competency Requirements

DHAttack 案例 / DHAttack Case Study

1. 某评估仿真系统主控平台项目总结 / Master Control Platform Project for an Evaluation and Simulation System

StructKernelBench 案例 / StructKernelBench Case Study

1. StructKernelBench:面向结构仿真的 CPU/GPU 核心算子优化实验平台 / A CPU-GPU Structural Simulation Kernel Optimization Platform

本页目录

CWFrame v0.1 26/3/25 前端渲染逻辑总结 / CWFrame Frontend Rendering Architecture Review ​

一、技术栈概览 ​

类别技术
框架Vue 3 (Composition API + TypeScript)
构建工具Vite
3D 渲染Three.js
3D 控制器OrbitControls (Three.js 官方示例)
图论可视化Vue-Flow (仅引用,未深度使用)
类型定义@shared/contract

二、核心数据流 ​

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│  world-data.json│     │  mock-progress.ts│     │  cwframe.loader │
│  (框架图数据)    │     │   (用户进度)      │     │    (加载器)     │
└────────┬────────┘     └────────┬─────────┘     └────────┬────────┘
         │                       │                        │
         └───────────────────────┼────────────────────────┘
                                 ▼
                        ┌─────────────────┐
                        │    App.vue      │
                        │  (状态管理)      │
                        └────────┬────────┘
                                 │
              ┌──────────────────┼──────────────────┐
              ▼                  ▼                  ▼
    ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
    │  CWFrameGraph   │ │  CWFrameNode    │ │  CWFrameLabel   │
    │  (Three.js 3D)  │ │  (Vue DOM 标签)  │ │   (详情弹窗)     │
    └─────────────────┘ └─────────────────┘ └─────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

三、模块详解 ​

1. 数据加载层 (core/cwframe.loader.ts) ​

函数作用
loadFrameMap()读取 world-data.json,返回 CWFrameMap
loadProgress()读取 mock-progress.ts,返回 CWFrameProgress

当前实现:直接从本地文件读取,后续将改为调用后端 API。


2. 状态计算层 (core/cwframe.status.ts) ​

typescript
type CWFrameNodeStatus = 'Locked' | 'Discoverable' | 'Unlocked';

// 节点状态判断逻辑
function getNodeStatus(node, progress):
  - 已解锁 → Unlocked
  - 未解锁但依赖全满足 → Discoverable
  - 依赖未满足 → Locked
  - 首次加载(无任何解锁)→ 全部隐藏为 Locked
1
2
3
4
5
6
7
8
状态表现
Locked3D 节点不渲染,DOM 标签不显示
Discoverable3D 节点暗淡显示,DOM 标签隐藏
Unlocked3D 节点高亮,DOM 标签显示,可点击

3. 进度操作层 (core/cwframe.progress.ts) ​

函数作用
unlockNode(progress, node)将节点加入 unlockedNodes
lockNode(progress, node)从 unlockedNodes 中移除
resetProgress(progress)重置所有进度

当前逻辑:开放式探索,用户输入匹配即解锁,不检查依赖。


4. 主组件 (App.vue) ​

状态定义 ​

typescript
frameMap: CWFrameMap           // 框架图数据
progress: CWFrameProgress      // 用户进度
nodePositions: Map             // 3D→2D 坐标映射
selectedNodeId: number|null   // 当前选中的节点
inputValue: string             // 用户输入
matchResult: { success, message }
1
2
3
4
5
6

核心方法 ​

方法触发时机作用
onMounted页面加载调用 loader 加载数据
handleInputUnlock输入框回车/点击按钮匹配标签→解锁节点
handleNodeClick点击节点切换选中状态
handlePositionsUpdateThree.js 每帧更新 2D 坐标映射
handleReset点击重置按钮清空进度

模板结构 ​

App.vue
├── CWFrameGraph (Three.js 画布)
│   ├── 接收 frameMap, progress
│   └── 发出 nodeClick, positionsUpdate
├── CWFrameNode (Vue 标签覆盖层)
│   ├── v-for 未锁定的节点
│   ├── 定位依据 nodePositions
│   └── 发出 click
├── Teleport → CenterPopup (详情弹窗)
│   └── CWFrameLabel
└── InputPanel (搜索框 + 按钮)
1
2
3
4
5
6
7
8
9
10
11

5. 3D 渲染组件 (components/CWFrameGraph.vue) ​

这是最复杂的组件,负责 Three.js 场景管理。

初始化流程 (initThree) ​

  1. 场景:创建 THREE.Scene,加雾效 FogExp2
  2. 相机:PerspectiveCamera,位置 (0, 0, 400)
  3. 渲染器:WebGLRenderer,透明度背景
  4. 控制器:OrbitControls,支持拖拽旋转,限制距离 100-800
  5. 背景:创建 2000 个星点粒子 Points
  6. 布局:调用 initLayout() 构建节点和连线
  7. 动画循环:requestAnimationFrame 渲染

节点布局算法 (buildStableNodePositions) ​

┌─────────────────────────────────────────────┐
│ 输入:nodes (含 id, category, dependencies) │
├─────────────────────────────────────────────┤
│ 1. 构建深度图 (依赖链层数)                    │
│ 2. 按 category 分扇区 (环形分布)              │
│ 3. 同 depth + category 的节点线性排列         │
│ 4. 半径 = baseRadius + depth * layerGap    │
│ 5. 加入稳定噪声避免重叠                       │
│ 输出:Map<nodeId, Vector3>                  │
└─────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10

节点对象结构 (createNode) ​

THREE.Group
├── sphere    (SphereGeometry, 半径8, 半透明核心)
├── glow      (SphereGeometry, 半径12, 外层光晕)
└── sprite    (CanvasTexture 渐变, AdditiveBlending)
1
2
3
4

连线逻辑 (createLink) ​

  • 遍历所有节点的 dependencies
  • 创建 THREE.Line,连接依赖节点 → 当前节点
  • 透明度根据两端状态动态调整

坐标映射 (updateScreenPositions) ​

3D 节点位置 ──project(camera)──> 归一化坐标 (-1~1)
                                    │
                                    ▼
                              转换为屏幕像素坐标
                                    │
                                    ▼
                    emit('positionsUpdate', Map)
1
2
3
4
5
6
7

触发频率:每帧最多 30ms 一次(节流),由 OrbitControls 的 change 事件驱动。

可见性更新 (updateNodeVisibility) ​

状态sphereglowsprite透明度
Unlocked显示显示显示高
Discoverable显示显示显示低
Locked隐藏隐藏隐藏-

连线的可见性:

  • 两端都是 Unlocked → opacity 0.6
  • 有一端 Unlocked → opacity 0.15
  • 其他 → 隐藏

交互 (onMouseClick) ​

  • 使用 Raycaster 检测点击
  • 只有 Unlocked 节点可点击
  • 触发 emit('nodeClick', nodeId)

6. DOM 标签组件 (components/CWFrameNode.vue) ​

属性说明
node节点数据
status状态 (Unlocked/Discoverable/Locked)
screenX/screenY来自父组件的 2D 坐标
selected是否被选中

定位:绝对定位,left: screenX px; top: screenY px,transform: translate(-50%, -50%)

样式:

  • Unlocked:显示球体 + 文字 + 发光
  • Discoverable:仅显示暗淡球体,隐藏文字
  • Locked:opacity: 0,不响应点击

7. 详情弹窗组件 (components/CWFrameLabel.vue) ​

通过 Vue Teleport 渲染到 body 下:

html
<Teleport to="body">
  <div v-if="selectedNode" class="center-popup">
    <CWFrameLabel :node="selectedNode" />
  </div>
</Teleport>
1
2
3
4
5

显示内容:label + description + category


四、调用关系图 ​

                    ┌─────────────────────────────────────┐
                    │           App.vue                    │
                    │  onMounted: loadFrameMap, loadProgress │
                    └──────────────┬──────────────────────┘
                                   │
              ┌────────────────────┼────────────────────┐
              ▼                    ▼                    ▼
   ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐
   │ cwframe.loader  │  │ cwframe.status  │  │ cwframe.progress │
   │ - loadFrameMap  │  │ - buildStatusMap │  │ - unlockNode     │
   │ - loadProgress  │  │ - getNodeStatus │  │ - resetProgress  │
   └────────┬─────────┘  └────────┬─────────┘  └──────────────────┘
            │                      │                      │
            ▼                      ▼                      ▼
   ┌─────────────────────────────────────────────────────────────┐
   │              CWFrameGraph.vue (Three.js)                   │
   │  - initThree: Scene/Camera/Renderer/Controls               │
   │  - buildStableNodePositions: 3D 布局算法                    │
   │  - createNode: 创建球体+光晕+sprite                         │
   │  - createLink: 绘制依赖连线                                 │
   │  - updateScreenPositions: 3D→2D 坐标映射                   │
   │  - updateNodeVisibility: 根据状态更新透明度                  │
   │  - onMouseClick: Raycaster 点击检测                         │
   └───────────────────────────┬─────────────────────────────────┘
                               │
            @node-click, @positions-update
                               ▼
   ┌─────────────────────────────────────────────────────────────┐
   │              CWFrameNode.vue (DOM 标签)                     │
   │  - 接收 screenX/Y 定位到 3D 节点对应位置                     │
   │  - 根据 status 渲染不同样式                                  │
   │  - 点击触发 @click → handleNodeClick                       │
   └───────────────────────────┬─────────────────────────────────┘
                               │
            点击已解锁节点
                               ▼
   ┌─────────────────────────────────────────────────────────────┐
   │              Teleport → CenterPopup                         │
   │  └── CWFrameLabel.vue (显示详情)                            │
   └─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

五、关键算法 ​

1. 深度计算(拓扑排序) ​

typescript
function buildDepthMap():
  1. memo = {}, visiting = Set()
  2. 对每个节点递归计算深度
  3. depth = 1 + max(所有依赖的depth)
  4. 避免循环依赖导致无限递归
1
2
3
4
5

2. 3D 布局(稳定位置) ​

typescript
function buildStableNodePositions():
  1. 按 depth + category 分组
  2. 环形分布:扇区角度 = 2π / category数量
  3. 径向距离 = base + depth * layerGap
  4. 加入 sin 噪声避免重叠
1
2
3
4
5

3. 屏幕坐标投影 ​

typescript
vec.setFromMatrixPosition(group.matrixWorld)  // 世界坐标
vec.project(camera)                          // 归一化设备坐标 (-1~1)
screenX = (vec.x * 0.5 + 0.5) * width        // 转像素
screenY = (-vec.y * 0.5 + 0.5) * height
1
2
3
4

六、后续扩展方向 ​

  1. 后端 API 对接:cwframe.loader.ts 改为 fetch 调用
  2. 依赖检查:解锁时验证依赖是否已解锁
  3. 持久化:解锁后调用 API 保存进度
  4. 更多节点样式:不同 category 使用不同颜色
  5. 交互优化:拖拽节点、缩放动画

七、文件索引 ​

路径作用
src/main.tsVue 入口
src/App.vue主组件,状态管理
src/core/cwframe.loader.ts数据加载
src/core/cwframe.status.ts状态计算
src/core/cwframe.progress.ts进度操作
src/components/CWFrameGraph.vueThree.js 3D 场景
src/components/CWFrameNode.vueDOM 标签层
src/components/CWFrameLabel.vue详情弹窗
src/data/world-data.json框架图数据
src/data/mock-progress.ts模拟进度数据
shared/contract.tsTypeScript 类型定义

最后更新于:

Pager
上一篇1. 计算机宇宙探索器 / Computer Universe Explorer
下一篇3. 🛡️ Computer-WorldFrame 项目技术面试指南 / A Technical Interview Guide for the Computer-World Frame Project

持续记录,持续成长

Copyright © Tidenflow