Compare commits

...
1 Commits
Author SHA1 Message Date
fukunee 7498409c7d README:新增国家/城市名贴地 TODO 2026-09-19 17:58:22 +08:00
+44 -19
View File
@@ -1,13 +1,13 @@
# 人类文明里程碑 · 活页编年史
一个以 **Three.js** 为核心、艺术化呈现世界历史里程碑的三维网站。它以一只**活页本**为隐喻,把历史中里程碑式的人、事、物登记成一张张两面活页:正面是登记卡(编号 / 时间 / 地区 / 名称 / 描述),背面是程序化生成的"铅笔素描"。
一个以 **Three.js** 为核心、艺术化呈现世界历史里程碑的三维网站。它以一只**活页本**为隐喻,把历史中里程碑式的人、事、物登记成一张张两面活页:正面是登记卡(编目号 / 时间 / 地区 / 名称 / 描述),背面是程序化生成的"铅笔素描"。
## 三种视图
| 视图 | 内容 |
| --- | --- |
| **活页本** | 皮革封面 + 金属活页环 + 20 张双面活页,翻页动画、纸张弯曲、堆叠阴影 |
| **时间轴** | 20 张活页沿金色时间轴一字排开,选中卡片上浮并显示年代 |
| **活页本** | 皮革封面 + 金属活页环 + 全部词条双面活页(正面登记卡、背面素描),翻页动画、纸张弯曲、堆叠阴影 |
| **时间轴** | 全部词条活页沿金色时间轴等距排开,上方常显主题、轴下方常显时间;点击/左右键选中并居中 + 翻面(纸张弯曲动画) |
| **地理** | Cesium 三维地球:卫星影像 + 真实地形 + 国界/城市标注 + 词条便签标记 |
## 地理视图(Cesium)
@@ -15,8 +15,8 @@
地理视图使用 **Cesium**(懒加载,进入该视图才加载脚本),免费、无需 Ion token:
- **影像/地形**:ESRI World Imagery 卫星影像(限制 ±85°)+ Esri World Elevation 3D 真实地形。
- **国界**:Natural Earth 50m,黑色单线。
- **国家/城市名**:Natural Earth + GeoNames 中文名,黑边黄字(`FILL_AND_OUTLINE`),按距离淡出,背面经深度测试隐藏。
- **国界**:Natural Earth 110m,黑色单线。
- **国家/城市名**:Natural Earth(10m 城市点,直接使用其 `name_zh` 中文名),黑边黄字(`FILL_AND_OUTLINE`),按距离淡出,背面经深度测试隐藏。
- **词条便签**:DOM 覆盖层(非 billboard),贴地形高度,逆时针 45° 斜放、平滑曲线箭头;未选中金底黑字带黑边,选中黑底金字。
- **交互**:左键旋转、滚轮缩放(500 m ~ 8000 km)、右键原生 tilt(松手不回正)、中键回正(flyTo 动画)。
- **画质**:按设备像素比渲染(高分屏清晰)、FXAA + MSAA、地形 `maximumScreenSpaceError=2.0`。
@@ -26,9 +26,12 @@
- **Three.js**(ES 模块 + Vite)渲染全部三维内容,`OrbitControls` 供旋转/缩放。
- **程序化纹理**:纸张、皮革、活页孔、登记卡、素描全部由 Canvas 2D 即时生成,无需外部图片。
- **程序化素描**:18 种手绘风格速写(头骨、泥板、金字塔、人像、神庙、王冠、斗兽场、卷轴、骑士、帆船、地球仪、苹果、蒸汽机、自由钟、进化树、原子、和平鸽、火箭),带抖动线条与排线阴影,同一词条每次渲染结果确定一致。
- **程序化素描**:53 种手绘风格速写(化石、泥板、金字塔、人像、神庙、王冠、斗兽场、卷轴、骑士、帆船、地球仪、苹果、蒸汽机、自由钟、进化树、原子、和平鸽、火箭、书、桥、旗帜、天平、剑、头盔、齿轮……),带抖动线条与排线阴影,同一词条每次渲染结果确定一致。
- **双面活页**:正面用 `FrontSide`、背面用 `BackSide`(内容预先水平镜像),配合纸张柔性弯曲,翻页时自然显露背面素描。
- 数据(`src/data/entries.js`)包含 20 条真实历史里程碑,含经纬度与分类(人 / 事 / 物)。
- 数据(`src/data/entries.js`)包含 182 条真实历史里程碑,含经纬度、分类(人 / 事 / 物)与档案式编目号。
- **编目号**:每页登记 `NO.{时间}-{地区}-{序号}`,如 `NO.BCE3-AFETNE-I0001`。时间=BC/AD 两位世纪,或 BCE1–BCE4 地质年代(1万/10万/100万/1000万年前);地区=大洲码+国家码+方位码(如 AFETNE=非洲·埃塞俄比亚·东北部);序号前缀 E/P/T/I/B(事件/人物/学说技术/文物/建筑)。
- **时间轴交互**:拖拽左右滑动、滚轮缩放;点击卡片 / 左右键 / 底部按钮 选中并平滑居中 + 翻面(带纸张弯曲动画),选中另一张时其它翻到背面的卡片自动翻回正面。
- **文字清晰度**:文字精灵 2 倍超采样栅格化;页面纹理以完整分辨率(768×1075)上传,避免降采样发糊。
## 性能优化(已完成)
@@ -38,10 +41,17 @@
- **双面材质合并**:页面正反面合并为单 mesh(`gl_FrontFacing` 双纹理),draw call 减半;活页孔用 alphaTest 免透明排序。
- **Cesium 懒加载 + 后台预载**:首屏不加载 6MB 脚本,首帧后后台预载,地理按钮就绪前在循环切换中自动跳过。
- **地理数据 primitive 化**:7342 城市点/标签与约 240 国家名标签由 entity 改为 `PointPrimitiveCollection` / `LabelCollection`。
- **渲染分辨率**:DPR 上限 1.5、Cesium 关闭超采样、页面纹理关闭 mipmap、anisotropy 8→4。
- **渲染分辨率**:Three.js 像素比上限 2(`min(devicePixelRatio, 2)`)+ MSAA 抗锯齿、Cesium 开 FXAA,三视图清晰;页面纹理关闭 mipmap、anisotropy 8→4。
- **时间轴专项**:拖拽期间暂停纹理生成(避免滑动时同步 canvas 绘制掉帧);时间轴视图关闭阴影贴图、灯光 5→2;刻度线合并为单个 LineSegments。
- **射线检测节流**:hover 合帧到渲染循环,只测可见窗口对象(binder 当前页 ±1、时间轴可视窗口)。
- **gzip**:Nginx 开启 gzip(含 `application/octet-stream`),geojson 3MB→1MB、城市 641KB→182KB。
## 翻页交互
- **空间点击翻页**:按命中点的空间左右半区判定方向——书脊右侧向前翻、左侧向后翻,翻页过程中也不受页索引错位影响。
- **松开触发**:左键「松开且未拖拽(≤4px)」才翻页;拖拽旋转视角不会误翻页。
- **首尾回卷 + END 页**:最后一页再向前进入 END 页——末页翻到左侧露出其背面素描;END 页向前回卷到第一页,第一页向后直接快进到 END 页,首尾闭环,底部导航联动显示「END」。
## 运行
```bash
@@ -51,6 +61,13 @@ npm run build # 生产构建(dist/)
npm run preview # 预览生产构建
```
生成 / 切换词条数据(跑完重新 `npm run build`):
```bash
python scripts/gen_entries.py # 182 条真实词条(含坐标去重、编目号、素描分配)
python scripts/gen_entries_stress.py # 1000 条压力测试数据
```
## 部署
### 1. 构建
@@ -94,11 +111,11 @@ curl -s -o /dev/null -w "%{http_code}\n" https://hist.fukun.net/
## 操作
- **拖动** 旋转视角,**滚轮** 缩放
- 地理视图:**左键拖拽** 旋转、**滚轮** 缩放、**右键拖拽** 倾斜环视(松手不回正)、**中键** 回正
- **← →** 或底部按钮 翻页(翻面查看背面素描)
- 点击 活页 / 时间轴卡片 / 地球标记 选中词条
- 顶部按钮或按键 **1 / 2 / 3** 切换 活页本 / 时间轴 / 地理 视图
- **活页本**:拖动旋转、滚轮缩放;点击书页右侧向前/左侧向后(松开触发);**← →** / 底部按钮翻页;第一页再向后 / 最后一页再向前回卷到 END 页
- **时间轴**:拖拽左右滑动、滚轮缩放;点击卡片 / **← →** / 底部按钮 选中并居中 + 翻面
- **地理**:左键拖拽旋转、滚轮缩放(右键 tilt、中键回正);点击标记选中
- 底部导航栏按钮(或按键 **1 / 2 / 3**)切换 活页本 / 时间轴 / 地理 视图
- 右下角登记卡在各视图间保持显示
## 目录结构
@@ -110,21 +127,29 @@ src/
scene/timeline.js 时间轴视图
scene/CesiumGlobe.js 地理视图(Cesium 地球、国界、城市、词条便签)
textures/pages.js 纸张 + 登记卡/素描两面纹理
textures/sketch.js 程序化素描生成器
data/entries.js 历史词条数据
textures/sketch.js 程序化素描生成器(53 种)
data/entries.js 历史词条数据(182 条)
ui/overlay.js HTML 覆盖层
ui/loading.js 加载遮罩
utils/ 缓动 / 文字精灵
scripts/ 截图与验证辅助(开发用)
scripts/
gen_entries.py 生成真实词条(坐标去重、编目号、素描分配)
gen_entries_stress.py 生成 1000 条压力测试数据
region_codes.py 地区编码 + 条目类型分类
analyze/ascii/colorascii/shot/verify 开发辅助
public/
world-countries.geojson 国家边界(Natural Earth 110m)
world-cities-zh.json 城市点(Natural Earth 10m,中文名)
```
## TODO / 后续规划
- [ ] **纹理懒加载**:书页与时间轴卡片的 Canvas 纹理改为按需 / 增量生成。当前启动时一次性生成全部纹理(每条词条正反两面),在 1000 条词条压力测试下启动耗时约 6 秒;懒加载后应降到约 1 秒。
- [ ] **国家/城市名贴地(参考便签)**:当前国家名、城市名标签在地形起伏处“钉地”不准(`CLAMP_TO_GROUND` 表现不理想)。需参考词条便签的做法,用 `Cesium.sampleTerrain` 显式采样地形高度后设置标签锚点高度,使其真正贴合地形表面。
- [x] **纹理懒加载**:已完成(见「性能优化」——可见窗口按需生成 + 引用计数/LRU 释放)。
- [ ] **活页本分册**:为全部词条增加分册(分卷)机制——按历史时期或主题分组,顶部提供分册导航与切换,活页本只展示当前分册的内容,降低单册厚度、便于浏览。
- [ ] **时间轴时期划分**:时间轴轴线上标注中西方历史时期刻度(如中国朝代:夏商周 / 秦汉 / 隋唐 / 宋元明清;西方:古典时代 / 中世纪 / 文艺复兴 / 启蒙运动 / 工业革命等),作为背景衬托。
- [ ] **词条插入时间轴**:词条按其 `timeNumeric` 真实时间位置插入时间轴(当前为等距排列),使时期刻度与词条位置相互对应。
- [ ] **词条结构考究与排版优化**:重新审视 `entries.js` 数据模型(补充年代精度、文明圈、影响、关键词等字段),并优化登记卡正面排版(信息层级、留白、装饰细节)。
- [ ] **性能进一步优化**:继续排查渲染 / 显存 / 加载瓶颈(已做:纹理懒加载、按需渲染、几何降级、双面材质、gzip 等)。
- [ ] **边界测试修复**:尾页(第一页 / 最后一页)前后的边界情况,在地理视图与时间轴视图存在 bug,待修。
- [ ] **时间轴清晰度**:时间轴视图当前偏模糊,需排查(可能是卡片低分辨率纹理 256×358 或渲染分辨率导致)。
- [x] **首尾边界回卷**:活页本第一页 / 最后一页 / END 页边界已处理,首尾闭环。
- [x] **渲染清晰度**:像素比上限 2 + MSAA / FXAA 抗锯齿,三视图不再发糊。