347 lines
14 KiB
Markdown
347 lines
14 KiB
Markdown
# Wasteland 图标重做审计
|
||
|
||
审计时间:2026-07-17
|
||
|
||
输入资产:
|
||
|
||
- 图标板:`sessions/_attachments/43bd9ed6-2ba6-4c9d-bd9d-25b068cb4711.webp`
|
||
- 完整界面参考:`sessions/_attachments/f01c1388-b603-434a-b226-2ff5771d4925.webp`
|
||
- 现有图标:`public/assets/themes/wasteland/icons/*.png`
|
||
- 当前样式:`public/style.css`
|
||
|
||
结论:主 UI 控件不建议继续直接使用现有原色 PNG。推荐改为“清理后的 24px 单色 mask + CSS 暗金材质”,再按控件容器设置 16/18/20/24px 的显示尺寸。`status` 这类带绿色状态语义、头像/主题装饰类图标可以保留原色,但要重新裁切对应规格。
|
||
|
||
## 1. 参考界面实际显示尺寸
|
||
|
||
图标板原尺寸为 `1672x941`,每张卡片标注了 `16px / 24px / 32px` 三档逻辑使用尺寸。需要注意:标注是设计目标尺寸,不等同于源图中的物理像素;当前切片来自 32px 档展示图,源图里主体通常有 49-70px 宽高。
|
||
|
||
完整参考图同为 `1672x941`。按原尺寸查看和局部放大后,主要控件的实际显示尺寸约为:
|
||
|
||
| 区域 | 控件 | 参考图容器尺寸 | 图标视觉主体 | 对齐观察 |
|
||
| --- | --- | ---: | ---: | --- |
|
||
| 侧栏顶部 | 新会话主按钮 | `229x48` | `18-20px` | 图标+文字整体居中,图标不贴左边 |
|
||
| 侧栏顶部 | 新会话下拉按钮 | `51x48` | `10-12px` 宽、`7-9px` 高 | 小三角居中 |
|
||
| 侧栏顶部 | 搜索框 | `288x34` | `18-20px` | 图标左距约 `13px`,图标到文字约 `10px` |
|
||
| 项目列表 | 折叠/展开三角 | 行高约 `44-46px` | `10-12px` | 左侧垂直居中 |
|
||
| 项目列表 | 新建圆形加号 | 约 `28-30px` 圆按钮 | `14-16px` | 圆按钮居中,线条要比搜索更实 |
|
||
| 输入区上方 | 运行状态/模式 chip | 高约 `30-31px` | 状态点约 `8px`,下拉约 `8px` | 文字与图标同基线 |
|
||
| 输入区 | 输入框外框 | 约 `804x70` | 附件 `22-24px` | 附件没有明显方形底,靠左居中 |
|
||
| 输入区右侧 | 发送/队列/停止按钮 | 约 `42x42` | 发送 `24-28px`,停止 `17-20px` | 三个按钮等宽等高,间距约 `6px` |
|
||
| 消息卡右下 | 小动作按钮 | `29-30px` | `14-16px` | 适合单色小图标,不适合复杂材质 PNG |
|
||
| 侧栏底部 | 设置按钮 | 可点击区约 `34px` 高 | `18px` | 与文字标签水平对齐 |
|
||
| 侧栏底部 | 主题/星芒入口 | 可点击区约 `34px` 高 | `22-24px` | 星芒比齿轮略大才接近参考 |
|
||
|
||
当前 `public/style.css` 中 Wasteland 图标相关尺寸:
|
||
|
||
- `.new-chat-btn::before`:`24x24`
|
||
- `.session-search::before`:`20x20`
|
||
- `.attach-btn::before` / `.send-btn::before` / `.abort-btn::before` / `.settings-btn::before`:默认 `22x22`
|
||
- `.settings-btn`:`34x34`
|
||
- `:is(.settings-select, .mode-select)` 下拉背景:`14x14`
|
||
- 移动端 `.attach-btn/.send-btn/.abort-btn::before`:降到 `20x20`
|
||
|
||
主要偏差:参考图里“主按钮图标”和“输入区发送图标”不是同一套尺寸;当前 CSS 把大部分伪元素统一为 `22x22`,导致小动作按钮偏脏、大按钮又不够有冲击。
|
||
|
||
## 2. 现有 PNG 为什么显得糊、脏、比例怪
|
||
|
||
现有 PNG 全部是 `64x64 RGBA`,但它们不是干净矢量导出的图标,而是从有损 WebP 展示板里裁 32px 档,再透明化/统一画布得到的位图。抽检全部 17 个 PNG 后,问题集中在以下几点。
|
||
|
||
### 2.1 缩放链路过长
|
||
|
||
当前路径大致是:
|
||
|
||
```text
|
||
有损 WebP 展示板
|
||
→ 裁 32px 档的放大截图区域
|
||
→ 统一输出 64x64 PNG
|
||
→ CSS 再缩到 14/20/22/24px
|
||
```
|
||
|
||
浏览器最后会把 64px 的半透明阴影、暗边、高光全部平均到 20-24px。图标不会变“精致”,反而会把阴影糊成灰边。
|
||
|
||
### 2.2 alpha 过软,缺少清晰实心主体
|
||
|
||
PNG 的非透明像素几乎都是半透明像素。统计结果显示:
|
||
|
||
- 多数图标的半透明像素占比在 `96%-100%`
|
||
- `stop.png` 也有约 `92%` 半透明像素
|
||
- 非透明像素平均 alpha 普遍只有 `67-142/255`
|
||
|
||
这说明边缘和主体都偏软。缩小时,暗边会吞掉金色高光,尤其在黑铁背景上更明显。
|
||
|
||
### 2.3 有效主体尺寸不一致
|
||
|
||
代表性 PNG 的 alpha 边界如下:
|
||
|
||
| 图标 | PNG 画布 | alpha 主体边界 | 视觉问题 |
|
||
| --- | ---: | ---: | --- |
|
||
| `new-chat.png` | `64x64` | `55x54` | 星芒长尖角多,缩小后中心笔画变弱 |
|
||
| `search.png` | `64x64` | `54x54` | 圆环+手柄复杂,20px 时手柄容易糊 |
|
||
| `attachment.png` | `64x64` | `42x54` | 窄高图标,被统一方形缩放后显得瘦 |
|
||
| `send.png` | `64x64` | `54x49` | 纸飞机横向强,22px 时尖角仍可辨但高光变灰 |
|
||
| `stop.png` | `64x64` | `54x54` | 填充和外框过重,小尺寸像脏方块 |
|
||
| `settings.png` | `64x64` | `54x53` | 齿轮齿太多,22px 以下信息密度过高 |
|
||
| `dropdown.png` | `64x64` | `54x40` | 横宽纵矮,放进 `14x14` 背景后实际只有约 `14x10` |
|
||
|
||
同样放进 `22x22` 伪元素时,`attachment` 会显瘦,`stop/settings` 会显重,`dropdown` 会显矮,整体视觉重量不统一。
|
||
|
||
### 2.4 原色 PNG 不能响应 CSS 颜色状态
|
||
|
||
当前 hover/focus 主要改变 `color`、`background-color`、`border-color`。PNG 作为 `background-image` 不会跟随 `color` 改变,所以 hover 后按钮变亮,但图标仍是暗铜色,造成“按钮亮、图标脏”的割裂。
|
||
|
||
## 3. 逐控件建议尺寸与对齐
|
||
|
||
建议把“容器尺寸”和“图标主体尺寸”分开控制,不再一刀切 `22x22`。
|
||
|
||
| 控件 | 当前落点 | 建议桌面尺寸 | 建议移动尺寸 | 对齐建议 |
|
||
| --- | --- | ---: | ---: | --- |
|
||
| 新会话 | `.new-chat-btn::before` | `20x20` | `18x18` | `.new-chat-btn` 改回图标+文字整体居中,`gap: 10px` |
|
||
| 新会话下拉 | `.new-chat-arrow::before` | `12x8` 或 `14x9` | `12x8` | 按钮 `48-52px` 宽,三角居中;隐藏原文本 `▾` |
|
||
| 搜索 | `.session-search::before` | `18x18` 或 `20x20` | `18x18` | `left: 13px`,输入框 `padding-left: 42px` |
|
||
| 附件 | `.attach-btn::before` | `24x24` | `22x22` | 40px 按钮内居中;不要用实心按钮底色压住图标 |
|
||
| 发送 | `.send-btn::before` | `24x24`,主发送可到 `26x26` | `22x22` | 桌面建议按钮 `40-42px`,纸飞机略向右上视觉居中 |
|
||
| 停止 | `.abort-btn::before` | `18x18` 或 `20x20` | `18x18` | 与发送按钮同容器,但图标主体必须小一档 |
|
||
| 设置 | `.settings-btn::before` | `18x18` | `18x18` | 34px 点击区内居中;避免 22px 齿轮过密 |
|
||
| 下拉 select | `:is(.settings-select, .mode-select)` | `10x7` 或 `12x8` | `10x7` | `background-position: right 12px center`;不要用 `14x14` 方形 PNG |
|
||
|
||
补充建议:
|
||
|
||
- 消息卡角落动作按钮:容器 `30x30`,图标只用 `14-16px` mask。
|
||
- 项目折叠三角:使用 `10-12px` mask,不要复用 24px/32px 原色 PNG。
|
||
- 状态点/在线图标:如果要保留绿色,应单独重裁 `16px` 或 `20px` 原色图,不建议统一金色 mask。
|
||
|
||
## 4. 三种方案对比与推荐
|
||
|
||
| 方案 | 优点 | 缺点 | 适用范围 | 结论 |
|
||
| --- | --- | --- | --- | --- |
|
||
| 原色 PNG | 最接近图标板的金属纹理;不需要改 DOM;可保留绿色状态、头像等多色信息 | 当前资产来自有损截图且 alpha 过软;缩到 20px 会糊;hover/focus 不能自动变色;每个尺寸都要维护独立图片 | 装饰图标、状态图标、头像/主题入口、较大 32px 展示 | 不推荐作为主 UI 控件方案 |
|
||
| CSS mask | 形状和材质分离;可用 CSS 控制金色、hover、禁用、危险色;小尺寸更干净;同一 mask 可按控件调尺寸 | 会损失原图内部金属纹理;如果直接拿现有 PNG 当 mask,软 alpha 仍会残留;严格做好需要清理 mask 资产 | new-chat/search/attach/send/stop/settings/dropdown 等交互控件 | 推荐主路径 |
|
||
| 重新裁 24px | 保留原色质感;比 64px 再缩小更稳;实现成本中等 | 仍是位图,16px 以下会糊;hover 不能换材质;不同控件仍要分别调视觉重量 | 必须保留原色材质的 24px 常规按钮 | 可作为过渡或备用 |
|
||
|
||
推荐路径:
|
||
|
||
1. 主交互控件使用 CSS mask,但不要直接依赖当前软 alpha PNG;先从图标板重做清晰的 24px 单色 mask,或从现有 PNG 做阈值化/锐化后生成 `icons/masks/*.png`。
|
||
2. `new-chat/search/attach/send/stop/settings/dropdown` 全部走 mask + CSS 暗金材质。
|
||
3. `status/user/theme/ai` 这类多色或装饰语义保留原色,但分别重裁 `16/24/32px`,不要再统一 64px 后缩放。
|
||
|
||
## 5. CSS mask 规则建议
|
||
|
||
下面是基于当前 DOM 的精确 selector 规则。路径可以先指向现有 PNG 做验证;正式落地时建议替换为清理后的 mask 资产,例如 `assets/themes/wasteland/icons/masks/send.png`。
|
||
|
||
### 5.1 通用金色材质
|
||
|
||
```css
|
||
html[data-theme='wasteland'] {
|
||
--waste-icon-gold:
|
||
radial-gradient(circle at 32% 22%, rgba(255, 244, 196, 0.98) 0 10%, transparent 32%),
|
||
linear-gradient(135deg, #fff0bd 0%, #dfbd82 28%, #c49a5a 48%, #8f592b 72%, #f0d7aa 100%);
|
||
--waste-icon-gold-muted:
|
||
linear-gradient(135deg, #ead7ad 0%, #c49a5a 44%, #7b4c27 100%);
|
||
--waste-icon-danger:
|
||
linear-gradient(135deg, #f1b68d 0%, #b96849 48%, #6f2f24 100%);
|
||
--waste-icon-shadow:
|
||
drop-shadow(0 0 2px rgba(223, 189, 130, 0.42))
|
||
drop-shadow(0 1px 1px rgba(0, 0, 0, 0.82));
|
||
}
|
||
|
||
html[data-theme='wasteland'] :is(
|
||
.new-chat-btn,
|
||
.new-chat-arrow,
|
||
.attach-btn,
|
||
.send-btn,
|
||
.abort-btn,
|
||
.settings-btn
|
||
)::before,
|
||
html[data-theme='wasteland'] .session-search::before {
|
||
content: '';
|
||
display: block;
|
||
flex: 0 0 auto;
|
||
background: var(--waste-icon-gold);
|
||
filter: var(--waste-icon-shadow);
|
||
-webkit-mask-repeat: no-repeat;
|
||
mask-repeat: no-repeat;
|
||
-webkit-mask-position: center;
|
||
mask-position: center;
|
||
-webkit-mask-size: contain;
|
||
mask-size: contain;
|
||
}
|
||
```
|
||
|
||
### 5.2 new-chat
|
||
|
||
```css
|
||
html[data-theme='wasteland'] .new-chat-btn {
|
||
justify-content: center;
|
||
gap: 10px;
|
||
padding-inline: 16px;
|
||
}
|
||
|
||
html[data-theme='wasteland'] .new-chat-btn .new-chat-glyph {
|
||
display: none;
|
||
}
|
||
|
||
html[data-theme='wasteland'] .new-chat-btn::before {
|
||
width: 20px;
|
||
height: 20px;
|
||
-webkit-mask-image: url('assets/themes/wasteland/icons/new-chat.png');
|
||
mask-image: url('assets/themes/wasteland/icons/new-chat.png');
|
||
}
|
||
```
|
||
|
||
### 5.3 search
|
||
|
||
```css
|
||
html[data-theme='wasteland'] .session-search::before {
|
||
position: absolute;
|
||
left: 13px;
|
||
top: 50%;
|
||
z-index: 1;
|
||
width: 18px;
|
||
height: 18px;
|
||
transform: translateY(-50%);
|
||
pointer-events: none;
|
||
-webkit-mask-image: url('assets/themes/wasteland/icons/search.png');
|
||
mask-image: url('assets/themes/wasteland/icons/search.png');
|
||
}
|
||
|
||
html[data-theme='wasteland'] .session-search-input {
|
||
padding-left: 42px;
|
||
}
|
||
```
|
||
|
||
### 5.4 attach
|
||
|
||
```css
|
||
html[data-theme='wasteland'] .attach-btn::before {
|
||
width: 24px;
|
||
height: 24px;
|
||
-webkit-mask-image: url('assets/themes/wasteland/icons/attachment.png');
|
||
mask-image: url('assets/themes/wasteland/icons/attachment.png');
|
||
}
|
||
```
|
||
|
||
### 5.5 send
|
||
|
||
```css
|
||
html[data-theme='wasteland'] .send-btn::before {
|
||
width: 24px;
|
||
height: 24px;
|
||
-webkit-mask-image: url('assets/themes/wasteland/icons/send.png');
|
||
mask-image: url('assets/themes/wasteland/icons/send.png');
|
||
}
|
||
|
||
html[data-theme='wasteland'] .send-btn:hover::before {
|
||
background: var(--waste-icon-gold);
|
||
filter:
|
||
drop-shadow(0 0 4px rgba(223, 189, 130, 0.58))
|
||
drop-shadow(0 1px 1px rgba(0, 0, 0, 0.82));
|
||
}
|
||
```
|
||
|
||
### 5.6 stop
|
||
|
||
```css
|
||
html[data-theme='wasteland'] .abort-btn::before {
|
||
width: 18px;
|
||
height: 18px;
|
||
background: var(--waste-icon-danger);
|
||
-webkit-mask-image: url('assets/themes/wasteland/icons/stop.png');
|
||
mask-image: url('assets/themes/wasteland/icons/stop.png');
|
||
}
|
||
```
|
||
|
||
### 5.7 settings
|
||
|
||
```css
|
||
html[data-theme='wasteland'] .settings-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 34px;
|
||
height: 34px;
|
||
padding: 0;
|
||
font-size: 0;
|
||
}
|
||
|
||
html[data-theme='wasteland'] .settings-btn::before {
|
||
width: 18px;
|
||
height: 18px;
|
||
-webkit-mask-image: url('assets/themes/wasteland/icons/settings.png');
|
||
mask-image: url('assets/themes/wasteland/icons/settings.png');
|
||
}
|
||
```
|
||
|
||
### 5.8 dropdown
|
||
|
||
`new-chat-arrow` 是普通按钮,可以直接用 mask:
|
||
|
||
```css
|
||
html[data-theme='wasteland'] .new-chat-arrow {
|
||
font-size: 0;
|
||
line-height: 0;
|
||
}
|
||
|
||
html[data-theme='wasteland'] .new-chat-arrow::before {
|
||
width: 12px;
|
||
height: 8px;
|
||
background: var(--waste-icon-gold-muted);
|
||
-webkit-mask-image: url('assets/themes/wasteland/icons/dropdown.png');
|
||
mask-image: url('assets/themes/wasteland/icons/dropdown.png');
|
||
}
|
||
```
|
||
|
||
`settings-select` 和 `mode-select` 是原生 `select`,当前 DOM 没有外层专用 wrapper,不能安全地只给箭头使用 `::before` mask。当前结构下推荐继续用金色 SVG 背景;如果强制用 CSS mask,需要新增 wrapper 或自定义 select 结构。
|
||
|
||
当前 DOM 兼容规则:
|
||
|
||
```css
|
||
html[data-theme='wasteland'] :is(.settings-select, .mode-select) {
|
||
appearance: none;
|
||
-webkit-appearance: none;
|
||
background-image:
|
||
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.25 6 6.75 11 1.25Z' fill='%23dfbd82' stroke='%238f592b' stroke-width='0.8'/%3E%3C/svg%3E");
|
||
background-repeat: no-repeat;
|
||
background-size: 12px 8px;
|
||
}
|
||
|
||
html[data-theme='wasteland'] .settings-select {
|
||
background-position: right 12px center;
|
||
}
|
||
|
||
html[data-theme='wasteland'] .mode-select {
|
||
background-position: right 10px center;
|
||
}
|
||
```
|
||
|
||
若后续允许改 DOM,建议把 select 放进 `.select-shell`,由 `.select-shell::after` 承载 dropdown mask,这样文本和箭头可以完全分层。
|
||
|
||
### 5.9 移动端尺寸
|
||
|
||
```css
|
||
@media (max-width: 560px) {
|
||
html[data-theme='wasteland'] .new-chat-btn::before,
|
||
html[data-theme='wasteland'] .session-search::before,
|
||
html[data-theme='wasteland'] .settings-btn::before {
|
||
width: 18px;
|
||
height: 18px;
|
||
}
|
||
|
||
html[data-theme='wasteland'] :is(.attach-btn, .send-btn)::before {
|
||
width: 22px;
|
||
height: 22px;
|
||
}
|
||
|
||
html[data-theme='wasteland'] .abort-btn::before {
|
||
width: 18px;
|
||
height: 18px;
|
||
}
|
||
}
|
||
```
|
||
|
||
## 6. 实施优先级
|
||
|
||
1. 先把 `new-chat/search/attach/send/stop/settings/new-chat-arrow` 改成 mask 方案,解决主路径视觉脏和 hover 不一致。
|
||
2. 同步把 select 下拉从 `dropdown.png` 改成金色 SVG 背景,尺寸降到 `12x8` 或 `10x7`。
|
||
3. 再生成清理后的 mask 资产,替换当前 PNG mask 源。清理标准是:去掉暗色投影,只保留形状 alpha;小尺寸下需要比原图更粗、更少内部细节。
|
||
4. 最后再决定是否为 `status/user/theme/ai` 重裁原色 `16/24/32px`,这些不应阻塞主交互控件修复。
|