diff --git a/.workbuddy/memory/2026-10-20.md b/.workbuddy/memory/2026-10-20.md index 417eefd..0de8f0d 100644 --- a/.workbuddy/memory/2026-10-20.md +++ b/.workbuddy/memory/2026-10-20.md @@ -124,3 +124,43 @@ `git check-ignore -v outputs/x` 确认命中。 - 另两条同样无效的规则没动:`./workbuddy`(目录根本不存在,笔误)、`./scripts`(有 1 个文件被跟踪)。 用户只要求 outputs;要清理得单独确认。 + +## 13:10 生成器能力盘点(含实测) + +用户问「有什么改进建议」,顺手实测了一个之前没验证过的点:**窄屏(390 宽)**。 + +- 没有 `@media` 规则的主题,在 390×844 下:16:9 桌面背景被 `cover` 裁成一条无意义纹理, + 人物被占满屏的卡片完全盖住 —— 等于白配。 +- shiroko 因为手写了 `@media (max-width:900px)`(换 `scene-mobile.webp` + deco 全关), + 同一视口下背景是协调的竖版、装饰退场。 +- 结论:**生成器导出的主题没有窄屏段**,这是真实缺口,不是理论问题。 + +其它已确认的缺口(grep 过,不是猜):无 localStorage / 无 json 导入导出(关掉全丢)、 +无图层上移下移(遮挡关系由顺序决定,只能删了重加)、无导出前校验、无既有主题导入。 + +⚠️ 测窄屏时必须让 **iframe 宽度**一起变(`verify.html?w=390`)。第一次只改外层 window, +iframe 内部仍是 1512,媒体查询按 1512 判定 → 结论是错的。 + +## 14:20 生成器补 P0 四项 + +用户问建议 → 我给了 P0/P1 清单 → 他选「P0 四条一起做」。已实现并推送。 + +1. **配置留得住**:`localStorage` 自动草稿(renderAll 后 700ms debounce)+ `theme-.json` + 保存/打开(图片 base64 内嵌,单文件带走);zip 里也塞一份 json;`?fresh=1` 跳过恢复。 +2. **图层 ↑↓**:顺序即层级(`background-image` 第一层画在最上)。 +3. **窄屏段**:竖版背景图 + 隐藏装饰 + 断点(默认 900),导出 `@media` 块。 + ⚠️ **只写浅色规则**:深色块特异性 0,2,1 > 浅色 0,1,1,本来就压住它;多写一份反而容易出错。 +4. **导出前校验**:slug / 图片层缺图 / 引用已删素材 / 超 10 层 / + 生成 CSS 每处装饰是否真 10 个值(与 Go `TestDecoSlotCount` 同规则,给工具自身兜底)。 + +**实测** +- 390 视口首层装饰 `url(char.webp)` → `none`,1512 下不变;两种视口都 12 层对齐。 +- 草稿往返:带 `?demo=1` 保存 → 不带 demo 打开,`validate` 仍为空(说明恢复成功)。 +- 示例 CSS 过 `TestThemeCSSComplete` + `TestDecoSlotCount`(27 处声明)。 + +**踩到的小坑** +- `makeDemo()` 里 `S.assets.push` 不检查重复 → 重复点「载入示例」会撞 id(`assetById` 取第一个), + 导出时静默用错图。改成开头 `S.assets = []`。 +- 拖拽标签写 `top:-17px` 会贴到画板边缘被压线/裁切,改成放在框内左上角; + 整块半透明填充会把人物罩成一层米色(看着像"框住空气"),改为纯虚线 + 角标签。 +- 面板一多左栏就滚不到底:按使用频率重排(图层 → 背景 → 窄屏 → 图片池 → 配色)。 diff --git a/dev/theme-builder/index.html b/dev/theme-builder/index.html index 338d73f..cea4aeb 100644 --- a/dev/theme-builder/index.html +++ b/dev/theme-builder/index.html @@ -1384,13 +1384,13 @@ function makeDemo(){ gc.bg = 'bg'; gc.layers = [ Object.assign(newLayer('image'), { asset:'char', h:420, ah:'start', av:'end', dx:40, dy:-36 }), - Object.assign(newLayer('radial'), { color:'#fff6d8', alpha:0.5, r:300, cx:20, cy:88 }), + Object.assign(newLayer('radial'), { color:'#ffd9a0', alpha:0.42, r:320, cx:20, cy:86 }), ]; const ac = S.scopes.admin; ac.inherit = false; ac.bg = null; - ac.layers = [Object.assign(newLayer('radial'), { color:'#fff3cf', alpha:0.4, r:340, cx:88, cy:12 })]; + ac.layers = [Object.assign(newLayer('radial'), { color:'#ffcf9a', alpha:0.38, r:380, cx:86, cy:10 })]; S.curLayer = null; S.scopes.box = blankScope('box');