# Q 主题接入 六款预设共用设置、主题单选、配置保存、Host 表面适配和安装生命周期。主题只提供自己的配色、静态插画和可选动效适配器。 ## 框架边界 - `src/shared.ts`:主题 ID、默认值和安全读取。月阙清霜排在首位,作为新配置、缺省和无效主题的默认值;已保存的有效主题、关闭和静态选择保留。`qThemeSettings[themeId].motion` 按主题独立保存。 - `src/client/theme-catalog.ts`:主题注册表,包含文案、插画、强调色、配色 CSS 和可选 `installScene`。可通过 `bannerPosition`、`previewPosition` 指定共用设置页的插画裁切位置,让人物避开预览气泡。注册表按 `Q_THEME_IDS` 排序,并通过 `Record` 检查是否遗漏主题。 - `src/client/q-theme.ts`:每个 Document 共享一个展示层。切换主题先销毁旧动效,再替换配色和插画;静态模式只停止动效。最后一个使用者卸载时恢复原主题标记并释放展示层。 - `src/client/q-theme.css`:共用侧栏装饰、阅读纸面、输入框、菜单、Todo、会话标签、浅深色和辅助功能适配。配色留在 `themes/*.css`,不复制整份展示层。 - `src/client/index.tsx`、`styles.css`:由注册表生成选择卡片和当前主题预览。整卡点击、圆形勾选和描边使用卡片自身的主题色;支持键盘方向键、Home/End。只有 Host 接受保存后的快照会改变选中状态。 - `src/client/theme-preview.tsx`:设置页在自己的同源 Document 中复用公共安装器和原场景适配器。动态选项显示实际动画,静态选项释放动效资源;关闭面板、退出视口或页面隐藏时停止预览,不影响主界面场景。 主题切换不修改 Harness 自己的浅深色偏好、代码高亮和错误/成功/警告等语义色,也不修改工具开关。 ## 新增主题 1. 在 `Q_THEME_IDS` 和 `DEFAULT_Q_THEME_SETTINGS` 添加 ID 和默认动静态设置;Host schema 根据 ID 列表生成。 2. 添加静态插画,并在 `scripts/build.mjs` 中作为 data URL 打包到 `brand-assets.ts`。运行时不依赖远程图片。 3. 新建 `src/client/themes/.css`,提供浅色和深色 token;静态图使用 `__QYT_THEME_SCENE__` 占位。不要复制公共布局规则。 4. 在中英文 locale 添加名称、说明、阅读提示和动效控件标签。 5. 在注册表新增 `ThemeDefinition`。共用设置页会自动生成卡片、圈选和动静态入口。 6. 如需动效,提供 `installScene(doc): () => void`。动效必须不接管用户交互,遵循减少动态效果、高对比度和页面可见性,并在卸载时释放帧、监听和观察器。不可用时保留静态插画。 鲸与海沿用原有 WebGL 动效、鼠标视差、涟漪和输入区镜像。大鱼海棠使用透明 Canvas 的花瓣与微光,不对女孩或鱼做鲸鱼式形变。两者共享上层框架,场景自身的绘制逻辑由各自的适配器维护。 ## 验证 ```sh npm run typecheck npm run build node --test tests/q-theme.test.mjs tests/ocean-scene.test.mjs tests/begonia-scene.test.mjs tests/settings-features.test.mjs tests/host-package.test.mjs npm run test:ocean:settings node scripts/test-q-themes.mjs ``` 浏览器预览使用本地模拟 Host,不连接真实账号,也不会更新正在使用的插件安装。 ## 落日山野 `sunset` 是第三个独立预设,插画为 `assets/q-sunset-scene.jpg`。暖色调浅深色配色独立保存,复用 `landscape-scene.ts` 的轻柔鼠标视差与漂浮微光。动效层只移动插画,不移动原生控件或阅读纸面;页面隐藏、退出视口、减少动态效果和主题卸载时停止并释放动画。主题卡片列表在独立滚动区域显示。 ## 月阙清霜 `moonfrost` 是独立的修仙预设,使用已确认的清冷女仙与月下云海背景 `assets/q-moonfrost-scene.jpg`,构建时内嵌到客户端。配色定义在 `themes/moonfrost.css`:浅色为银蓝纸面,深色为冷月墨蓝,阅读区沿用公共纸面遮罩。主题卡片、圆形选择标记、选中描边、中英文文案和独立动静态设置均由公共框架提供。 动态模式通过 `moonfrost-scene.ts` 将裙摆、披帛与发梢分别作为局部变形,补景填补移动后的空隙,脸、身体、腿和高跟鞋保持静止。该绘制器复用 `landscape-scene.ts` 的帧率、飘雪、可见性与清理生命周期。静态模式保留原画;减少动态效果、高对比度、页面隐藏和卸载时沿用公共适配器的暂停与清理逻辑。 阅读纸面在浅色下为 72%、深色下为 78% 的不透明度,让会话中的背景和裙摆更明显;浅色次级文字同步加深,两种外观的小字在纸面覆盖最黑/最白图片像素时仍达到 4.5:1 对比度。 所有内置主题和自定义主题的主侧栏、设置窗口左侧导航共用全高插画与半透明渐变遮罩,背景以 cover 填满,避免底部小图的分界;自定义主题沿用用户设置的图片位置。公共适配层还覆盖主框架、插件页、自动化任务页、轨迹等会话视图、右侧文件与文档预览、分栏/浮动面板、标签栏和弹窗。各面板使用同一视口坐标的插画与纸面,避免分栏后各自放大人物。PDF、Office 文档、代码高亮与终端内容继续由原渲染器绘制;图片仅用于应用外壳和留白。`scripts/test-theme-harness.mjs` 使用独立 profile 验证官方 Harness 的真实页面,不操作用户配置。 ## 不良人 · 玄冥夜行 `buliangren` 是第五款独立预设,沿用用户确认的不良帅、月夜城阙、玄黑暗金与朱砂红效果。静态原画为 `assets/q-buliangren-scene.jpg`,补景为 `assets/q-buliangren-clean-plate.jpg`,均为 1672×941;构建时作为 data URL 内嵌,运行时不请求外部图片。素材通过内置 imagegen 从确认稿去除界面后生成,补景仅移除人物并延续原有城阙。浅色使用暖纸与古金,深色使用墨黑、暗金和朱砂色发送按钮,阅读遮罩在浅色为 62%、深色为 70% 不透明度,减轻底图上的全局洗色,并调整文字明暗,让会话中的背景更清晰、小字仍满足 4.5:1 对比度。 `buliangren-scene.ts` 为云、雾、披风/红色飘带和头发提供独立分区与低频风场;云层纹理局部缓移,雾气轻移并缓慢改变浓淡,衣料与发梢按固定端距离增加摆幅。面具、斗笠、手、腰带、躯干与主要建筑保持静止。原有月阙清霜和本主题共用 `layered-scene-art.ts` 的图片注册检查、RGB 蒙版、补景合成、GPU 资源与失败回退,实际帧循环仍归 `landscape-scene.ts` 管理。 红色枫叶复用公共 `landscape-atmosphere.ts` 的花瓣轨迹,使用五裂枫叶轮廓、叶脉和红色渐变,数量限制为 36 片,粒子独立加速 2.8 倍(场景速度为 1.05,实际落叶速度约为首版的 3.5 倍);阅读时收拢至两侧。静态模式不安装绘制器与枫叶,设置页预览和主界面分别遵循公共可见性、减少动态效果、高对比度与卸载清理。动静态选择按主题独立保存,升级不改动现有主题或默认主题。 验证: ```sh npm run typecheck npm run build node --test tests/q-theme.test.mjs tests/landscape-scene.test.mjs tests/settings-features.test.mjs tests/host-package.test.mjs node scripts/test-buliangren-scene.mjs node scripts/test-moonfrost-scene.mjs node scripts/test-q-themes.mjs npm run test:ocean:settings ``` 分区 GPU 检查实际比较云、雾、头发、披风与飘带的像素变化,并断言面具、斗笠、躯干、腰带与建筑区域不动;帧截图和结果位于 `artifacts/buliangren-scene/`。主题切换、浅深色、窄窗口和输入穿透截图位于 `artifacts/q-themes/buliangren-*.png`;卡片选择、动态预览、静态保存及刷新恢复由实际设置页检查。 首页标题、鲸鱼标记及工作区/模式/Git 分支行使用统一暖金色 `#E6C58B`,仅覆盖首页内容区的文字 token,输入卡片恢复正常阅读色,菜单继续使用独立表面配色。侧栏遮罩进一步降为浅色 58%、深色 64%,同步调整侧栏文字颜色。月前云层使用独立的柔边流云层掠过固定月盘,不移动月亮、斗笠或面具;周围云层仍使用原画分区流动。 ## 用户自定义主题 设置页右侧的「+ 新建主题」打开独立编辑弹窗。编辑窗口的按钮、滑块、边框和空白预览区跟随当前应用主题,上传图片后的实时预览独立展示草稿主题。支持导入 JPG、PNG、WebP 静态图,调整缩放与画面位置,选择轻柔视差/缓慢平移/呼吸缩放/轻盈浮动/环绕漫游,以及微光/花瓣/飘雪/萤火/星芒/气泡/极光氛围。氛围色独立于界面主题色,可用色轮、明度滑块、HEX 输入和柔和预设色选择,也可恢复各效果的默认配色;旧主题无需迁移。支持动效强度、0.10×–5.00× 速度、主题色和阅读遮罩。支持浅深色预览、重新编辑和删除。内置的「落日山野」始终是独立预设,不会被自定义编辑覆盖。 - 内置主题仍由 `Q_THEME_IDS` 注册;自定义记录使用 `custom:`,由 `getQThemes` 在运行时合并。自定义名称是用户文本,不作为 locale key 或 CSS 代码执行。 - `src/custom-themes.ts` 定义记录和边界;Host schema 与客户端读取均限制图片类型、ID、颜色和数值。源图上限 10 MiB/4000 万像素,客户端重新编码为最长边 1600 像素、最多 256 KiB 的图片,每份配置最多 8 个自定义主题。 - 压缩图片和参数一起保存在 Host 的 `qCustomThemes` 配置中,通过既有配置服务持久化及同步到客户端。无需远程图床或额外图片 API,不依赖关闭页面后失效的 Blob URL。图片未保存前只留在编辑草稿;临时 Blob URL 在处理完成后释放。这里选择有界内嵌图片,避免新增一套资源存储和孤儿文件清理流程。 - 「保存并应用」在一次带配置版本校验的原子写入中保存记录和当前主题。失败保留草稿;取消不写入。编辑页发现同一主题已被其他窗口修改时拒绝覆盖,需重新打开读取最新版本。删除当前自定义主题会在同次写入中切回默认主题 `moonfrost`。 - `custom-theme-definition.ts` 将安全记录转换为配色、插画和通用动效参数。同 ID 的内容改变也会更新样式和重建动效。静态模式、隐藏预览、减少动态效果沿用公共生命周期。 - 主题选择器为固定高度的 flex 布局。只有 `.qyt-theme-choices` 卡片区域使用 `overflow-y:auto`,标题与「+ 新建主题」是它的同级元素,所以滚动卡片不会带走新增按钮。 - 编辑弹窗使用原生模态 dialog,点击外部空白与 Escape 不关闭,只有明确的取消/关闭按钮才丢弃草稿;编辑内容独立滚动,页头和保存按钮固定在弹窗内;窄窗口下也可以保存、取消或删除。 验证: ```sh npm run typecheck node --test tests/custom-themes.test.mjs tests/q-theme.test.mjs tests/landscape-scene.test.mjs tests/begonia-scene.test.mjs tests/settings-features.test.mjs node scripts/test-custom-themes.mjs npm run test:ocean:settings node scripts/test-q-themes.mjs ``` 浏览器测试验证上传、草稿隔离、浅深色预览、保存拒绝与重试、重载持久化、静态模式、取消、删除、窄窗口布局,以及列表实际滚动时新增按钮的位置保持不变。截图输出到 `artifacts/custom-themes/`。 自定义氛围使用有数量上限的渐变装饰层,花瓣带透光层次、星芒缓慢闪烁、气泡保留高光与透明边缘,极光以宽幅柔光缓慢游移。阅读状态将粒子收拢至两侧、降低极光亮度,动效强度为零时不显示氛围。所有新增效果共用景观动效生命周期,遵循系统减少动态效果与强制颜色设置,并在隐藏、离屏和卸载时暂停或释放。 ## AI 智能动态主题 自定义主题编辑器使用横向工作台:左侧是大预览和原图区域修正画布,右侧以「图片」「智能动效」「氛围与配色」三个面板组织操作;整体播放、强度和速度固定在右侧底部。对象列表默认收起,只显示当前选中的对象,展开后切换对象会自动收起;重新分析设置在生成后默认折叠。宽度不足 980px 时上下排列;页头、保存和取消操作始终可达,桌面两侧可以独立滚动。 - `src/smart-motion.ts` 定义版本化的动作方案。对象名称、数量、轮廓、固定点和动作参数来自实际图片分析,不预置“头发/衣服/云雾/水面”的对象列表。第一版提供随风摇曳、柔和波浪、缓慢流动、局部涟漪、轻盈浮动和明暗呼吸六种通用模板;不生成新的肢体动作。 - `src/features/smart-theme/host.ts` 通过 Harness 的 `llm` 和 `attachments` 服务调用已配置、声明支持图片的 DeepSeek Flash 路由。界面不提供模型下拉框,Host 根据 Harness 的实时目录自动选择当前账号可用的最新视觉模型;依据能力声明识别型号,不维护旧型号白名单。列表遗漏能力时查询确切模型元数据,生成时再次自动解析路由。界面自动重试目录发现,不要求已登录用户另行配置模型,不接收密钥或任意 API 地址。生成前和绑定调用后都检查视觉能力。请求有大小、输出长度、并发和时限边界,支持取消;仅接受通过 Host owner 身份检查的调用。图片内文字按数据处理,不执行模型输出的代码。 - 图像导入在压缩配置预览图前保留独立的高质量工作图,去除原图元数据。AI 分析和局部分层使用工作图;原有主题预览图仍限制为最长边 1600px、最多 256KiB。 - 整图分析只用于发现对象和带上下文的裁剪范围,不将粗多边形直接当作人物对象的最终选区。`smart-segmentation-worker.ts` 在本机使用固定版本 SlimSAM/ONNX WASM,以 5×5 网格点生成像素候选,按 IoU 去重并保留最多 24 个形状有差异的候选。`smart-theme-processing.ts` 将原图与洋红色真实蒙版制作成编号对照图;每个对象单独交给视觉模型选择编号,避免整张大拼图缩小后混淆脸、皮肤和发丝。候选选出后,再将单个真实蒙版放大到 960×480 独立确认;无可靠候选或确认未通过时返回 -1 并剔除对象,不按分割最高分直接采用,也不要求视觉模型精确输出像素坐标。 - 分割权重、WASM 和模块只使用固定来源与 SHA-256 校验,缓存在当前 profile 的 `qiuya-motion-runtime/`;首次约下载 25MB。分割在浏览器 Worker 中单线程执行,复核后立即释放未采用的候选画布,图片不会发送给模型下载站。视觉分析和每个对象的复核会产生 DeepSeek 用量;多候选比较预留足够的视觉推理额度,单蒙版确认关闭思考并限制短输出。复核失败重试时,相同图片和偏好复用已有整图分析;播放、调速、保存和重载不调用模型。 - 最终像素蒙版叠加手动画笔,减去保护区域并做颜色边界细化和柔边;用户可以涂抹运动、擦除、保持静止和撤销。生成后直接播放;进入修正页会明确提示暂停,并提供返回动态预览按钮。分割后的 sway/wave 将固定点和末端贴合实际像素蒙版,允许边缘轻柔移动,以邻近纹理延伸填补窄缝;其他类型主要做内部变形或亮度变化。补景不是生成式语义修复,大幅运动、复杂遮挡和细发丝仍有限制。视觉复核也可能判断错误,必须用真实图片、最终蒙版和视频检查,确定性 UI fixture 只证明界面与播放链路。 - 准备好的原图、背景补景、三张 RGB 蒙版图集和保护图,组成不可变、按 SHA-256 寻址的素材记录,保存于当前 profile 的 `qiuya-theme-assets/`。单份记录最多 8MiB,profile 最多 128 份/96MiB;未保存的编辑草稿只保留在有界客户端缓存中。素材写入使用临时文件和原子重命名;读取验证内容摘要。主题配置只存素材 ID、源图摘要和小型动作配方,避免大量图层进入配置。 - `smart-theme-art.ts` 将源图、柔边区域和固定点交给通用 WebGL 绘制器,采用低频风场、按固定点距离限制幅度和单次逆向采样合成,重叠区域共享位移,灯光仅轻微明暗变化;加载后用平滑渐入避免突然跳动。旧版蒙版在内存中升级柔边,无需再次调用模型。绘制器继承 `landscape-scene.ts` 的可见性、减少动态效果和卸载清理。源图或蒙版签名不匹配、素材不可用或 GPU 失败时保留静态背景。调整对象幅度、速度和方向无需再次请求模型;几何和笔画变更才重新准备素材。保存和重载、主题播放均不调用模型。 - 素材文件属于当前 Host profile;只复制主题配置到其他 profile 并不能搬迁素材。生成结果在点击保存前只存在于草稿。取消、关闭、替换图片或重新生成会立即释放未采用的客户端蒙版和临时素材;保存失败后撤回未引用的磁盘素材,支持原草稿重试。已保存主题的删除与替换会回收不再引用的素材。Host 在串行写入队列内检查实时主题引用和其他正在保存的草稿租约,避免误删共享素材。历史遗留文件仍受总量配额约束,后续可增加带引用检查的导出、导入界面。 验证命令: ```sh npm run typecheck node --test tests/smart-theme.test.mjs tests/custom-themes.test.mjs tests/host-package.test.mjs node scripts/test-smart-themes.mjs ``` `tests/fixtures/smart-theme/moonfrost-plan.json` 是使用项目自带插画实际调用 DeepSeek Flash 得到的分析记录(保护区域标注已规范为轮廓)。回归测试使用该记录,不再次产生 API 用量;验证横向工作台、动态对象、涂抹修正、GPU 像素变化、素材保存重载、静态/减少动态效果和窄窗口布局。截图、实际 GPU 输出录制的视频及兼容 GIF 位于 `artifacts/smart-theme/`。 ## 桃华白狐 · 视频主题 `fox` 使用用户提供的 `1105.mov` 转码为 1600×898 的 H.264/AAC MP4,保留原声音轨并循环播放。桃粉/梅紫配色复用公共阅读纸面、主题卡片、浅深色和静态模式;主界面封面 `assets/q-fox-scene.jpg` 来自视频 2 秒处。侧栏使用用户选定的候选 05(5.1 秒),独立素材为 `assets/q-fox-sidebar.jpg`,以 44% 水平位置竖向裁切;静态模式显示这张粉色静帧;动态模式的侧栏直接透出全局视频,浅色遮罩为 52%、深色为 60%。 - 视频独立托管在 GitHub Release,安装包只包含两张小型静态图片、固定下载地址、字节数与 SHA-256;构建不读取或内嵌 MP4。`src/theme-video.ts` 管理资源描述,后续更新必须使用新的附件名及校验值。 - `src/features/theme-video/host.ts` 首次收到 owner 请求才下载视频,并缓存到当前 profile 的 `qiuya-theme-videos/.mp4`。相同下载请求合并;响应流限制大小、校验完整长度与摘要,通过后原子落盘。后续启动离线读取缓存;缓存损坏时重新下载。客户端不能传 URL 或文件路径。 - 视频与设置页预览始终静音,不显示音频开关或视频说明提示;旧配置中保存的 `muted: false` 不再影响播放。 - `video-scene.ts` 优先在包含左侧栏、主内容与右侧栏的原生 frame 挂载一个视频。所有面板只叠加阅读遮罩,透出同一解码帧与同一画面坐标,避免时间差、分栏裁切错位与重复解码;会话、插件页、自动化任务等主内容页切页保留播放进度。小预览使用带同样侧栏与主内容插槽的独立 frame,整个预览共用一层视频,保持与实际界面相同的构图和同步关系。视频不接管点击。输入区外侧移除静态背景镜像,直接透出同一视频。页面隐藏或离屏时暂停;静态、减少动态效果、高对比度、主题关闭或卸载时释放播放器与 Blob URL。下载中、失败或解码错误保留封面;重新切换动静态可重试。主界面与预览分别管理资源,Host 下载缓存共用。 验证:`node --test tests/theme-video.test.mjs tests/q-theme.test.mjs tests/settings-features.test.mjs tests/host-package.test.mjs`、`node scripts/test-video-theme.mjs`、`node scripts/preview-ocean-settings.mjs`。实际视频解码、循环、固定静音、隐藏暂停、无障碍回退、根节点替换与卸载验证记录在 `artifacts/video-theme/`,设置页浅深色与窄窗口截图在 `artifacts/ocean-scene/fox-settings-*.png`。浏览器检查只使用独立测试 profile。