Files
cc-web/.trellis/tasks/07-17-gilded-wasteland-theme/research/asset-slicing.md
2026-07-18 10:14:38 +08:00

281 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 暗金荒野主题资产切片研究
生成时间:2026-07-17T16:41:28+08:00
## 输入资产
- 背景图:`sessions/_attachments/094d7907-875d-41f4-9985-992c87c9b9cc.webp`
- 图标板:`sessions/_attachments/43bd9ed6-2ba6-4c9d-bd9d-25b068cb4711.webp`
- 完整界面参考:`sessions/_attachments/f01c1388-b603-434a-b226-2ff5771d4925.webp`
三张图尺寸均为 `1672x941`,格式为 RGB WebP,无 alpha 通道。
坐标约定:本文所有裁剪框均使用 `[x, y, w, h]`,其中 `x+w` / `y+h` 是右边界 / 下边界的排他坐标。由于源图是有损 WebP,边缘估算建议按 `±3px` 处理;真正导出时可再外扩 `2-4px` 做抗锯齿和阴影保留。
## 背景图定位与遮罩建议
### 视觉结构
- 左侧 `x=0-740` 是较干净的暗色烟雾区,适合承载侧边栏、搜索框、会话列表和中左侧主内容。
- 右侧 `x=920-1560, y=80-760` 是人物、法阵和权杖主体,视觉权重高,不适合直接压大段正文。
- 下方 `y=780-941` 有烟尘、碎石和暗部,可放输入框,但输入框自身需要较实的半透明面板。
- 背景平均亮度很低,左侧安全区采样亮度约 `22/255`,右侧人物区约 `38/255`;遮罩目标不是继续压暗整图,而是稳定文本和边框对比。
### 推荐 CSS
桌面端推荐保留人物在右中部,同时让左侧和主聊天区域更稳:
```css
.theme-gilded-wasteland {
position: relative;
min-height: 100vh;
color: var(--gilded-text);
background-color: #050707;
overflow: hidden;
}
.theme-gilded-wasteland::before {
content: "";
position: fixed;
inset: 0;
z-index: -2;
background-image: url("/assets/theme/gilded-wasteland/background.webp");
background-size: cover;
background-position: 62% 50%;
background-repeat: no-repeat;
}
.theme-gilded-wasteland::after {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
background:
linear-gradient(
90deg,
rgba(4, 6, 6, 0.94) 0%,
rgba(4, 6, 6, 0.86) 18%,
rgba(4, 6, 6, 0.58) 48%,
rgba(4, 6, 6, 0.30) 70%,
rgba(4, 6, 6, 0.62) 100%
),
linear-gradient(
180deg,
rgba(0, 0, 0, 0.40) 0%,
rgba(0, 0, 0, 0.08) 24%,
rgba(0, 0, 0, 0.16) 70%,
rgba(0, 0, 0, 0.70) 100%
),
radial-gradient(
ellipse at 74% 34%,
rgba(216, 168, 92, 0.12) 0%,
rgba(216, 168, 92, 0.04) 22%,
transparent 42%
);
}
@media (max-width: 720px) {
.theme-gilded-wasteland::before {
background-position: 70% 50%;
}
.theme-gilded-wasteland::after {
background:
linear-gradient(90deg, rgba(4, 6, 6, 0.92), rgba(4, 6, 6, 0.76)),
linear-gradient(180deg, rgba(0, 0, 0, 0.42), rgba(0, 0, 0, 0.72));
}
}
```
### 定位取值
- 常规桌面:`background-position: 62% 50%`,人物仍在右侧,左中区域更可读。
- 参考图同尺寸复刻:`background-position: center center` 也可用,因为参考图本身没有裁切。
- 侧边栏更宽或主面板偏左时:可调到 `64% 50%`,避免人物头部过早进入主消息卡片。
- 移动端:建议 `70% 50%` 并提高遮罩不透明度,优先保证内容可读。
## 图标板网格边界
图标板不是透明 sprite,而是「暗色背景 + 金色边框 + 标题 + 三规格图标 + 尺寸标签」的展示板。建议把它作为切片源,不要直接拿整板做 CSS sprite。
### 列边界
| 列 | x0 | x1 | 宽度 |
| --- | ---: | ---: | ---: |
| C1 | 50 | 295 | 245 |
| C2 | 315 | 562 | 247 |
| C3 | 582 | 829 | 247 |
| C4 | 846 | 1092 | 246 |
| C5 | 1111 | 1358 | 247 |
| C6 | 1377 | 1621 | 244 |
### 行边界
| 行 | y0 | y1 | 高度 |
| --- | ---: | ---: | ---: |
| R1 | 50 | 187 | 137 |
| R2 | 201 | 339 | 138 |
| R3 | 354 | 490 | 136 |
| R4 | 506 | 641 | 135 |
| R5 | 655 | 786 | 131 |
| R6 | 798 | 927 | 129 |
### 卡片矩阵
| 卡片 | 名称 | 整卡裁剪框 `[x,y,w,h]` |
| --- | --- | --- |
| R1C1 | new chat | `[50,50,245,137]` |
| R1C2 | dropdown | `[315,50,247,137]` |
| R1C3 | search | `[582,50,247,137]` |
| R1C4 | shortcut | `[846,50,246,137]` |
| R1C5 | collapse / expand | `[1111,50,247,137]` |
| R1C6 | add (circle) | `[1377,50,244,137]` |
| R2C1 | theme / star | `[50,201,245,138]` |
| R2C2 | ai swirl | `[315,201,247,138]` |
| R2C3 | status (online) | `[582,201,247,138]` |
| R2C4 | loading | `[846,201,246,138]` |
| R2C5 | attachment | `[1111,201,247,138]` |
| R2C6 | send | `[1377,201,244,138]` |
| R3C1 | stop | `[50,354,245,136]` |
| R3C2 | settings | `[315,354,247,136]` |
| R3C3 | user / profile | `[582,354,247,136]` |
| R3C4 | terminal / prompt | `[846,354,246,136]` |
| R3C5 | copy | `[1111,354,247,136]` |
| R3C6 | delete | `[1377,354,244,136]` |
| R4C1 | refresh | `[50,506,245,135]` |
| R4C2 | folder | `[315,506,247,135]` |
| R4C3 | chat bubble | `[582,506,247,135]` |
| R4C4 | notification | `[846,506,246,135]` |
| R4C5 | upload | `[1111,506,247,135]` |
| R4C6 | download | `[1377,506,244,135]` |
| R5C1 | info | `[50,655,245,131]` |
| R5C2 | warning | `[315,655,247,131]` |
| R5C3 | close | `[582,655,247,131]` |
| R5C4 | check | `[846,655,246,131]` |
| R5C5 | lock | `[1111,655,247,131]` |
| R5C6 | eye / visibility | `[1377,655,244,131]` |
| R6C1 | fullscreen | `[50,798,245,129]` |
## 常用图标推荐裁剪框
默认建议切 32px 规格,因为它能向下缩放到 24px / 16px,且保留更多金属高光和阴影。下表是「图标主体裁剪框」,不包含卡片标题、尺寸标签和外框。
| 图标语义 | 来源卡片 | 32px 主体框 `[x,y,w,h]` | 备注 |
| --- | --- | --- | --- |
| new chat | R1C1 | `[204,85,69,65]` | 十字星形,外扩较多以保留长尖角 |
| search | R1C3 | `[746,86,62,62]` | 放大镜手柄在右下,透明化时保留阴影 |
| dropdown | R1C2 | `[480,98,59,45]` | 三角图标高度较小,可居中放入 32px 容器 |
| theme / star | R2C1 | `[204,236,70,65]` | 星芒很长,不建议再紧缩 |
| ai swirl | R2C2 | `[476,236,65,65]` | 旋涡近似正方形 |
| status / online | R2C3 | `[749,242,53,53]` | 需要把绿色填充计入 mask |
| attachment | R2C5 | `[1277,236,49,60]` | 回形针纵向更高,容器内垂直居中 |
| send | R2C6 | `[1533,237,63,57]` | 纸飞机尖角在右上 |
| stop | R3C1 | `[211,392,56,56]` | 方形停止按钮 |
| settings | R3C2 | `[476,389,65,62]` | 齿轮外齿需要保留 |
| user / profile | R3C3 | `[743,389,65,62]` | 头像圆框 |
| terminal / prompt | R3C4 | `[1009,393,59,55]` | 矩形外框有阴影 |
| copy | R3C5 | `[1278,392,48,56]` | 双页图标偏窄 |
| refresh | R4C1 | `[211,541,57,57]` | 圆箭头 |
| chat bubble | R4C3 | `[745,541,62,55]` | 气泡尾巴在左下 |
| close | R5C3 | `[749,690,53,53]` | X 形,适合放入 32px 方形容器 |
| check | R5C4 | `[1010,693,56,47]` | 勾号高度较小,容器内垂直居中 |
### 16px / 24px / 32px 自动裁剪规则
整卡内三个规格的位置基本稳定,推荐通过卡片边界自动切,而不是手工维护所有坐标。
1. 先按上文卡片矩阵定位目标卡片。
2. 在卡片内部建立三个横向检测带:
```text
16px: [card.x + 18, card.x + 70]
24px: [card.x + 82, card.x + 145]
32px: [card.x + 152, card.x + card.w - 20]
```
3. 纵向检测带取:
```text
[card.y + 35, min(card.y + card.h - 35, card.y + 100)]
```
4. 对检测带内像素建立图标 mask:
```text
gold = r > 75 && g > 48 && b < 90 && r >= g - 8 && r - b > 22
pale = r > 135 && g > 105 && b < 95 && r - b > 35
green = g > 70 && r < 95 && b < 80 && g - r > 8
mask = gold || pale || green
```
5. 对 mask 像素取最小外接矩形,再外扩 `4px` 得到主体裁剪框。
6. 如果要导出统一尺寸图标,把主体框透明化后放入固定画布:
| 源规格 | 推荐输出画布 | 用途 |
| --- | ---: | --- |
| 16px | `20x20` 或 `24x24` | 列表小图标、状态点 |
| 24px | `32x32` | 常规按钮 |
| 32px | `40x40` 或 `48x48` | 主操作按钮、头像旁标识 |
### 自动检测边界算法
卡片边界可以用金色边缘峰值检测自动恢复,适合后续批量生成 manifest。
```text
1. 读取 RGB WebP。
2. 计算相邻像素梯度:
edge = abs(r-r0) + abs(g-g0) + abs(b-b0)
3. 对 edge > 18 的像素分别累加到 x/y 投影。
4. 对投影做半径 1-2px 的平滑。
5. 在 x 轴选取强峰并按宽度 239-247px 配对,得到左右边界:
[50,295], [315,562], [582,829], [846,1092], [1111,1358], [1377,1621]
6. 在 y 轴选取强峰并按高度 129-138px 配对,得到上下边界:
[50,187], [201,339], [354,490], [506,641], [655,786], [798,927]
7. 用卡片位置矩阵给每个 cell 赋语义标签。
8. 在 cell 内按 16/24/32 检测带取主体 mask 外接框。
```
## 透明化与输出格式方案
### 图标透明化
源图标板是 RGB WebP,背景和图标都已经混合压缩,不能直接得到完美 alpha。推荐流程:
1. 从图标板按主体框裁剪,裁剪时外扩 `2-4px`。
2. 从裁剪框边缘做暗背景 flood-fill,把与边缘连通且亮度低、饱和度低的区域标记为背景。
3. 对非背景像素按亮度和色相生成 alpha:
- 金色 / 浅金高光:保留。
- 绿色状态图标:单独保留,避免被金色阈值漏掉。
- 暗色压缩噪点:alpha 压低到 `0`。
4. 对 alpha 做轻微 `1px` 羽化,减少 WebP 黑边。
5. 把图标居中放入统一画布,按钮内再用 CSS 控制 `width/height`。
建议保留一份 manifest,记录源图、源框和输出文件名,后续可重复生成:
```json
{
"search": {
"source": "43bd9ed6-2ba6-4c9d-bd9d-25b068cb4711.webp",
"card": "R1C3",
"variant": "32px",
"bbox": [746, 86, 62, 62],
"output": "icons/search-32.png"
}
}
```
### 输出格式
- 背景:保留 WebP 或转 AVIF/WebP 两套,作为 CSS 背景图,不需要透明通道。
- 图标主格式:透明 PNG。它对 alpha 最稳,适合切片后人工复核和 UI 直接引用。
- 图标 Web 优化:可额外导出 lossless WebP,使用 `image-set()` 或构建工具按浏览器能力选择。
- 不建议:直接用原始图标板做 CSS sprite。它包含展示卡片、标题、尺寸标签和暗纹理背景,透明化与 hover/filter 都会困难。
### 质量检查点
- 用深色、浅色、半透明按钮背景分别检查黑边。
- 对 `status / online` 单独检查绿色中心是否完整。
- 对 `new chat`、`theme / star`、`send` 检查尖角是否被裁掉。
- 对 `dropdown`、`check` 这类非方形图标,导出后应放入统一画布居中,而不是强行拉伸。