diff --git a/.workbuddy/memory/2026-10-20.md b/.workbuddy/memory/2026-10-20.md index 24112af..ce8a913 100644 --- a/.workbuddy/memory/2026-10-20.md +++ b/.workbuddy/memory/2026-10-20.md @@ -59,3 +59,19 @@ 构图硬约束(左侧 22% 前景必须是空地,否则又回到"站在课桌上")、换图清单与定位公式。 - 配色给的是**压白后的显示值** + 反算公式 `原色=(显示值-40.8)/0.84`,并特别标注袜子要用 `#ededed` 而不是纯白(纯白会和背景粘连,抠图必然吃穿)。 + +## 10:40 主题生成器(dev/theme-builder) + +- 单文件 `dev/theme-builder/index.html`:上传背景/人物/道具 → 拖拽调位置 → 导出 zip, + 解压到项目根即可新增主题。不联网、不起服务、图片全在浏览器本地转 WebP。 +- 预览用**和线上同一套机制**渲染(pattern + deco 6 层 + page-image,size/position 对齐), + 不是另画示意图;拖出来的「左沿像素」反解成 `calc(50% - Npx)`,换视口不跑位。 +- 导出包:`static/css/themes/.css` + `static/images/themes//*.webp` + `INSTALL-.txt`。 + CSS 同时写浅色/深色两块,10 个必需令牌齐全——**实测通过 `TestThemeCSSComplete`**。 +- zip 自己实现(STORE + CRC32,约 40 行),不引 CDN;`unzip -t` 无错。 +- 踩坑:① 面板里 `c.text2` 写成 undefined(light 对象里才算出来的派生色,要用 `light.text2`); + ② `contain` 模式如果不按内容裁画布,会留大片透明边 → 导出宽高比全错; + ③ 预览容器 `grid-template-columns:340px 1fr` 会被 1512px 的 frame 撑破 → `minmax(0,1fr)`; + ④ 无头 Chrome 下 `canvas.toBlob` 的回调在 `--dump-dom` 前不触发 → 全部改 `toDataURL` 同步化, + 自检才能跑(`?selftest=1` 输出 CSS/zip 字节,`?demo=1` 载入示例素材)。 +- ⚠️ 预览里深色必须走「暗色渐变 + deco none」,否则会拿白天场景图压深底(和导出结果不一致)。 diff --git a/dev/theme-builder/README.md b/dev/theme-builder/README.md new file mode 100644 index 0000000..bb43cfe --- /dev/null +++ b/dev/theme-builder/README.md @@ -0,0 +1,43 @@ +# 主题生成器(本地单文件) + +`index.html` 双击即用,不联网、不起服务、不传图片——所有处理都在浏览器本地完成。 + +## 用法 + +1. 打开 `dev/theme-builder/index.html`(推荐 Chrome / Edge)。 +2. 填 slug(= css 文件名,小写字母/数字/连字符)。 +3. 传图: + - **背景图**:任意尺寸,会按 `cover` 裁成 1920×1080; + - **人物**:透明底 PNG/WebP,会按高度 1.5× 输出; + - **道具**(可选):透明底,会自动在底部烘一层接触阴影。 +4. 拖预览里的虚线框调位置,或右侧滑杆微调;切 1512 / 1280 / 1024 看不同视口。 +5. 点「导出 zip」→ 解压到项目根目录 → 按 zip 里的 `INSTALL-.txt` 做三步(登记 `[theme] available`、`StaticVersion` +1、重新编译)。 + +## 它做了什么 + +- 用**和线上同一套机制**渲染预览:`background-image: pattern, deco(6 层), page-image`, + `background-size` / `background-position` 一一对应,不是另画一张示意图。 +- 位置数学和 CSS 一致:`background-position` 的百分比是相对 **(容器宽 − 图宽)**, + 所以工具里拖出来的「左沿像素」会被反解成 `calc(50% - Npx)`,换视口不会跑位。 +- 图片全部转 WebP 并按目标尺寸重采样,导出前就能看到 KB 数。 +- 生成的 CSS 同时写浅色/深色两块(项目测试 `TestThemeCSSComplete` 要求), + 10 个必需令牌齐全。 + +## 它不做什么 + +- **不抠图**。人物/道具必须是透明底;白底图导出的主题会带一块白。 +- **不做调色**。想统一"雾度"(人物压白 16%、场景 30~38%)得在生成端做, + 或用 `docs/theme-shiroko-assets-spec.md` 里的公式自己处理。 +- **不写 `[theme] available`**。配置在 `conf/app.ini`,导出包里只给了要粘贴的那一行。 +- **不改代码**。素材是编译期 embed,必须重新 `go build` 才会生效。 + +## 自检 + +``` +chrome --headless=old --dump-dom "file:///.../dev/theme-builder/index.html?selftest=1" +``` + +会把生成的 CSS 与 zip 字节以 JSON 塞进 `
`,可用于回归:
+把 `css` 写成 `static/css/themes/.css`,跑 `go test ./internal/theme -run TestThemeCSSComplete`。
+
+`?demo=1` 会直接载入示例素材(纯 canvas 画的渐变背景 + 一个剪影),没有图也能先看布局。
diff --git a/dev/theme-builder/index.html b/dev/theme-builder/index.html
new file mode 100644
index 0000000..4433e1f
--- /dev/null
+++ b/dev/theme-builder/index.html
@@ -0,0 +1,855 @@
+
+
+
+
+
+TamaBox 主题生成器
+
+
+
+
+
+

TamaBox · 主题生成器

+ 选图 → 调位置 → 导出 zip,解压到项目根目录即可 +
+ + +
+
+
+ + +
+
+
+ + + +
+
+ + +
+ + 拖虚线框调整位置 +
+
+
+
+ +
+
+
+
狼的提问箱
@admin6 · 收到 128 个问题 · 回答 96 个
+
+
全部已答待答
+
+

最近在看什么书?

+
《雪国》——冷得像今天的风。
+

怎么才能不被议题绑架?

+

有推荐的通勤耳机吗

+
+
+
社区规则备案号已运行 412 天
+
先上传一张背景图或点右上角「载入示例」先看效果
+
人物
+
道具
+
+
+
+
+
+
+ + + + + diff --git a/static/css/themes/_scaffold.css b/static/css/themes/_scaffold.css index cfc8db1..f904f60 100644 --- a/static/css/themes/_scaffold.css +++ b/static/css/themes/_scaffold.css @@ -1,5 +1,6 @@ /* ============================================================================ 主题底稿(scaffold)—— 复制本文件改名为 .css 即可新增一套主题。 + 不想手写 CSS 的话,用 dev/theme-builder/index.html 可视化生成(选图 / 拖位置 / 导出 zip)。 文件名即 slug:只允许小写字母、数字、连字符(如 sakura / ocean-mist)。 新增后需在 conf/app.ini 登记: