Skip to content

Repository files navigation

答案之书

一本可以轻触随机开启、滑动逐页翻阅的互动答案之书。

当前项目状态

  • 生产主版使用 CSS 3D 书体、独立书页纹理与 DOM 文字,优先保证纸面细节、文字清晰度和手机端性能。
  • 答案使用 crypto.getRandomValues() 等概率抽取,允许自然重复。
  • 滑动模式支持页数进度条:拖动时逐页翻动,点击时翻动一叠厚页。
  • 项目由 Cloudflare Worker Static Assets 部署,Worker 名称为 answers-within,账户子域名为 cloudiday.workers.dev
  • 默认主题为“森境”;“原典”主题继续保留,可在页面右上角即时切换。
  • 页面包含首次使用指南,并会根据用户采用轻触打开或滑动打开的方式,分阶段提示另一种操作,不强制完成全部手势。
  • 当前森林主题使用完整的绿色皮革封面、金色植物纹框、左右镜像羊皮纸书页、森林背景与萤火素材。
  • Three.js 3D 实验仍保存在 codex/three-experiment 分支,作为后续技术参考;原实验预览地址已不再作为当前生产入口。
  • Three.js 实验验证了实时柔性翻页,但当前存在材质偏旧、近距离网格感明显、动态文字纹理不够清晰等问题,因此没有作为生产主版。
  • 同一个 Worker 现已预留受 OAuth 保护的 /mcp 服务;公开网页没有新增私人题库入口,未登录请求无法读取工具或内容。
  • 私人题库第一阶段采用 D1 按用户隔离、AES-GCM 应用层加密和本地访问口令,先以 35 条测试种子验证完整流程,再扩充到真心话 150 条、大冒险 100 条、答案 100 条。

后期视觉优化方向

后期将根据效果测试,在以下两种路线中选择其一,或组合使用:

方案一:Blender 预渲染序列

  • 在 Blender 中完成书本建模、纸张材质、灯光、接触阴影和翻页动画。
  • 输出视频、WebP/AVIF 序列或精灵图,由网页手势和进度条控制播放帧。
  • 优点是最接近 Blender 最终渲染质量,没有实时低模网格感。
  • 适合固定镜头下的封面开启、单页翻动和薄/中/厚页叠动画。

方案三:Blender 与网页混合

  • 静止书本和重要翻页阶段使用 Blender 渲染素材。
  • 网页继续负责完全随机、412 条动态答案、进度条和清晰文字。
  • 翻页过程中隐藏文字,书页停稳后再由 DOM 文字贴合纸面浮现。
  • 可以保留 CSS 主版的清晰交互,同时获得 Blender 的材质与光影质感。

在新方案达到目标前,生产主版与实验分支应并行保留,不直接互相覆盖。

当前交互

  • 右上角主题按钮可在“原典”与“森境”之间即时切换;选择保存在浏览器本地,切换时不会重置答案、书本状态或翻页进度。
  • “森境”使用独立的森林背景、萤火、绿色皮革封面与左右镜像书页素材;“原典”样式继续完整保留,方便并行比较和继续探索。
  • 首次使用时会显示可视化操作指南;完成基础操作后,仍可在右上角通过“指南”重新打开。
  • 电脑与手机:轻点闭合书封随机打开;轻点摊开的书合上;再次轻点书封重新随机打开。
  • 电脑使用鼠标、手机使用手指在闭合书封上从右向左拖动,从第 000 页打开。
  • 页数轨道只在书本完全摊开后显示;无论以哪种方式打开,都可拖动轨道连续逐页翻动,或点击轨道翻动一叠厚页。
  • 摊开的书被轻点时合上;水平滑动时不合书,从左页开始回到上一页,从右页开始进入下一页。
  • 两种打开方式的答案都在原位由模糊到清晰浮现,不产生上下位移。
  • 开合动画以书脊为视觉锚点:打开时先抬起和展开纸页,落稳后显示文字与轨道;关闭时先隐藏内容,再收拢纸页和封面。
  • 封面、内封、纸块、书脊与摊开书页共用同一套 3D 坐标,不再通过两套书体重叠淡化,避免开合过程穿模。

私人 MCP(第一阶段)

MCP 与公开答案之书共用同一个 Worker,远程端点为:

https://answer-book.naginoumi.com/mcp

当前工具:

  • get_book_info:查看默认与个人题库数量。
  • draw_card:按 truthdareanswer 从默认、个人或混合题库完全随机抽取。
  • save_cards:把用户在当前对话里确认过的生成内容保存到个人题库;不会自动保存未确认内容。
  • list_my_cardsupdate_my_carddelete_my_card:管理当前登录用户自己的卡片。
  • get_my_preferencesset_my_preferences:保存生成风格、强度、场景与避开项。
  • export_my_book:导出当前用户自己的个人卡片和偏好。

隐私边界:

  • OAuth 令牌确定用户身份,数据库查询同时固定带上 owner_id;工具不接受调用方自行填写用户 ID。
  • 个人卡片和偏好在写入 D1 前使用每用户独立派生的 AES-GCM 密钥加密。
  • 生产环境关闭请求日志和链路追踪,不记录口令或私人正文。
  • 默认私人种子保存在被 Git 忽略的 .private-data/private-seed.json,不会提交到公开仓库。
  • 这些措施用于实现可靠的用户间隔离,但不宣称“绝对私密”:掌握 Cloudflare 账户与生产主密钥的运维者仍属于信任边界。

模型可以先根据当前聊天上下文和 get_my_preferences 生成候选内容,只有用户明确选择后才调用 save_cards。第一阶段不在 Worker 内另接一个固定模型,因此每个 MCP 客户端都能使用自己的模型和上下文。

本地初始化

npm run db:migrate:local
npm run private:key
npm run private:seed
npm run user:create -- <私人名字> "<显示名称>"
npm run dev

生成的主密钥、访问口令和私人种子都在 .private-data/.dev.vars 中,只保留在本机且不会进入 Git。生产初始化使用相同命令的 --remote 参数;执行远程迁移、设置密钥和创建用户后才能部署带私人 MCP 的版本。

修改答案

答案文字保存在:

public/data/aqi-answer-book.json

修改后运行 npm run check。检查脚本会验证 JSON 结构、答案数量、页码与重复 ID,避免格式错误进入部署版本。

本地运行

npm install
npm run dev

检查与部署

npm run check
npm run deploy:dry-run
npm run deploy

About

???????:??????,?????????

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages