PersonalWebApplication/docs/photo-wall.md

66 lines
3.7 KiB
Markdown
Raw Normal View History

# 照片墙 Photo Wall`#photo` 入口)
模拟软木板/墙面的互动照片展示页:上传本地照片,以宝丽来风格散落摆放,用胶带、
图钉、便签、贴纸、印章、手绘箭头自由装扮,可导出为一张 PNG。**纯前端**(无后端改动),
状态存浏览器 `localStorage`
设计来源:`photo-wall-design.docx`(产品设计文档 v1.0)。本页是其 React 重写版。
## 入口与鉴权流
地址栏 `#photo` 是一个**写死的公开入口**,与开发者入口门(`dev_gate`**无关**
```
浏览器 #photo
└─ 直接显示登录页(复用 LoginPage但去掉顶部服务器负载栏 ← 不查后端 gate
登录页提交用户名 + 密码
└─ POST /api/web/login → 校验同一套 ccuser 账号 → 成功后进入照片墙
```
- `#photo` **不走** `POST /api/web/gate`(藏门口令),但照片墙本身仍被登录挡住——
用的是同一套 `ccuser` 后端账号(见 [auth-login-gate.md](auth-login-gate.md))。
- **已登录**用户访问 `#photo` 会跳过登录页,直接进墙。
- 墙内右上角「退出」= 清登录态 + 抹掉地址栏 `#photo`,回到导航页(`StartPage`)。
## 涉及文件(全部前端)
- `Client/src/App.tsx` — 监听 `hashchange``#photo` 短路 gate`wantsPhoto`
已登录 + `wantsPhoto` → 渲染 `PhotoWallPage`,否则博客页。
- `Client/src/components/LoginPage.tsx` — 新增 `hideStats` 开关,隐藏顶部
`AnnouncementBar`(系统负载栏);把轮询的 `useSystemStats` 拆进只在显示时挂载的
`StatsBar` 子组件,隐藏时不发请求。
- `Client/src/components/PhotoWallPage.tsx` — 照片墙组件本体。
- `Client/src/index.css` — 末尾 `.pw-` 命名空间的全部照片墙美术样式(软木板/宝丽来/
便签折角/胶带/图钉等,无法用 Tailwind 表达的部分)。
> 后端零改动:登录走既有 `/api/web/login`,照片墙数据只存浏览器,不落服务器。
## 功能
- **照片**:宝丽来白边(底部加大留白)、随机旋转 ±15°、立体投影三种随机固定方式
(胶带 / 彩色图钉 / 双角胶带)。
- **交互**:拖拽移动、双击编辑标注、右键菜单(旋转 ±5°、放大/缩小、移到最前/最后、
删除;便签额外可改色)。触摸端长按 = 右键。
- **装饰**便签5 色 + 折角、胶带条、12 预设贴纸 + 自定义文字、SVG 印章、手绘箭头
(选中后在画布拖动绘制)。
- **背景**:软木板 / 黑板 / 白墙 / 牛皮纸,工具栏循环切换。
- **上传**:按钮选择 / 拖入画布 / 剪贴板粘贴(`FileReader` 读 Base64
- **历史**:撤销/重做 Ctrl+Z / Ctrl+Y最多 30 步。
- **持久化**:操作后防抖 1s 自动写 `localStorage`key `photo-wall-state`
`{ bgIndex, els }`);工具栏显示「保存中…/已保存」。
- **导出**`html2canvas`CDN 懒加载)截图画布为 `photo-wall-<时间戳>.png`
## 实现注记
- **拖拽性能**:拖拽过程中只直接改 DOM 的 `transform`GPU 合成),**不触发 React
重渲染**;松手后才一次性 commit 进状态并记一步历史。故拖拽中不得 `setState`
- 元素统一 Pointer Events 处理鼠标 + 触摸;`touch-action: none` 防止滚动抢手势。
- 「保存中…」由各改动入口mutate / undo / redo / 拖拽 commit / 换背景)打标,
防抖 effect 仅负责落盘并置「已保存」——避免在 effect 内同步 `setState` 引发级联渲染。
## 线上访问
部署后:`http://8.130.143.54:8548/#photo`(纯前端改动,按
[部署计划](superpowers/plans/2026-06-18-deploy.md)的 frontend-only redeploy 路径上线,
后端无需重启)。