Files
LanMountainDesktop/.trae/documents/weather-widget-visual-redesign.md

343 lines
15 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.
# 天气组件视觉重构 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 彻底重构阑山桌面天气系列组件的背景视觉和文字排版为每种图标风格Google Weather / Geometric / Breezy / Lemon提供独立的背景配色和视觉质感参考各天气 App 的 Material Design 风格,实现几何质感+柔和渐变+层次分明的排版。
**Architecture:** 保留现有数据层WeatherWidgetBase、WeatherSnapshot、WeatherIconAssetResolver和组件注册机制不变。核心改动1) 将 `MaterialWeatherVisualTheme.ResolvePalette()` 扩展为按 styleId 分派不同配色方案2) 重构 `MaterialWeatherSceneControl` 为按 styleId 渲染不同背景风格3) 改进各天气 Widget 的文字排版层次。先创建 HTML Mock 验证视觉效果。
**Tech Stack:** Avalonia UI (XAML + C# code-behind)、HTML/CSS (Mock 预览)
---
## 当前状态分析
### 现有天气组件体系
5 个天气组件,全部继承自 `WeatherWidgetBase`
| 组件 | 文件 | 功能 |
|------|------|------|
| WeatherWidget | `WeatherWidget.axaml(.cs)` | 基础天气:温度+状况+图标+位置 |
| WeatherClockWidget | `WeatherClockWidget.axaml(.cs)` | 天气+时钟 |
| ExtendedWeatherWidget | `ExtendedWeatherWidget.axaml(.cs)` | 扩展天气:含指标/小时/多日预报 |
| HourlyWeatherWidget | `HourlyWeatherWidget.axaml(.cs)` | 逐小时天气 |
| MultiDayWeatherWidget | `MultiDayWeatherWidget.axaml(.cs)` | 多日天气 |
### 核心问题
1. **背景与图标风格脱钩**: `MaterialWeatherVisualTheme.ResolvePalette()` 只返回一套配色,与 `WeatherVisualStyleId`GoogleWeatherV4/Geometric/Breezy/LemonFlutter完全无关。切换图标风格时背景不变。
2. **背景视觉单调**: `MaterialWeatherSceneControl` 只有一种手绘几何风格(椭圆+云+雨滴),质感差,缺乏各 App 的特色。
3. **文字排版粗糙**: 温度数字不够大,信息层次不分明,指标用纯文字堆叠,预报区域无卡片样式。
4. **半透明遮罩硬编码**: 所有组件都覆盖 `<Border Background="#30FFFFFF" />` 等硬编码遮罩,不随风格变化。
### 各天气 App 风格特征
**Google Weather (v4)**:
- 背景:大面积柔和蓝白渐变,晴天偏暖黄蓝,雨天偏深蓝灰
- 装饰:极简,几乎无几何装饰,纯靠渐变色彩表现天气氛围
- 排版温度超大72px+),天气状况中等,位置小字
**Geometric Weather (几何天气)**:
- 背景:深色系渐变(深蓝/深紫/深灰),搭配半透明几何圆形装饰
- 装饰:大面积半透明圆形叠加,营造深度感
- 排版:紧凑信息密度,指标用小标签
**Breezy Weather (微风天气)**:
- 背景:清新渐变(浅蓝/浅绿/浅紫),比 Geometric 更明亮
- 装饰:柔和波浪线条 + 少量几何装饰Material Design 风格
- 排版:卡片式预报,圆角芯片
**Lemon Weather (柠檬天气)**:
- 背景:暖色系渐变(橙黄/粉紫/暖蓝柠檬2偏扁平柠檬3偏Material
- 装饰:天气场景装饰(太阳光芒/云朵轮廓/雨丝),更有场景感
- 排版:温度超大,天气图标突出
---
## 设计方案
### 视觉论文 (Visual Thesis)
每种图标风格拥有独特的背景渐变配色和几何装饰语言——Google 纯净渐变、Geometric 深色几何、Breezy 清新波浪、Lemon 暖色场景——配合超大温度数字和层次分明的排版,在桌面小组件空间内实现 Material Design 的几何质感。
### 配色方案设计
每种风格 × 每种天气条件 × 昼夜 = 独立配色。以下为关键配色定义:
#### Google Weather 风格
| 天气 | 白天 Top→Bottom | 夜晚 Top→Bottom |
|------|----------------|----------------|
| Clear | #4FC3F7#B3E5FC | #0D47A1#1A237E |
| PartlyCloudy | #81D4FA#E1F5FE | #1565C0#283593 |
| Cloudy | #90A4AE#CFD8DC | #37474F#455A64 |
| Rain | #78909C#B0BEC5 | #263238#37474F |
| Storm | #546E7A#78909C | #1A1A2E#263238 |
| Snow | #E1F5FE#FFFFFF | #1A237E#283593 |
| Fog/Haze | #B0BEC5#ECEFF1 | #455A64#546E7A |
#### Geometric 风格
| 天气 | 白天 Top→Bottom | 夜晚 Top→Bottom |
|------|----------------|----------------|
| Clear | #1A237E#3949AB | #0A0E27#1A1A3E |
| PartlyCloudy | #283593#5C6BC0 | #0D1033#1E1E4A |
| Cloudy | #37474F#607D8B | #1A1A2E#2D2D44 |
| Rain | #1A237E#3F51B5 | #0A0E27#1A1A3E |
| Storm | #1A1A2E#3F51B5 | #050510#1A1A2E |
| Snow | #E8EAF6#C5CAE9 | #1A237E#283593 |
| Fog/Haze | #455A64#78909C | #1A1A2E#37474F |
#### Breezy 风格
| 天气 | 白天 Top→Bottom | 夜晚 Top→Bottom |
|------|----------------|----------------|
| Clear | #4DD0E1#80DEEA | #006064#00838F |
| PartlyCloudy | #4FC3F7#B2EBF2 | #00695C#00897B |
| Cloudy | #80CBC4#B2DFDB | #37474F#546E7A |
| Rain | #4DB6AC#80CBC4 | #004D40#00695C |
| Storm | #26A69A#4DB6AC | #1A1A2E#004D40 |
| Snow | #E0F7FA#FFFFFF | #006064#00838F |
| Fog/Haze | #80CBC4#E0F7FA | #37474F#546E7A |
#### Lemon 风格
| 天气 | 白天 Top→Bottom | 夜晚 Top→Bottom |
|------|----------------|----------------|
| Clear | #FFB74D#FFF176 | #1A237E#311B92 |
| PartlyCloudy | #FF8A65#FFCC80 | #283593#4A148C |
| Cloudy | #BCAAA4#D7CCC8 | #37474F#4E342E |
| Rain | #90A4AE#B0BEC5 | #1A1A2E#311B92 |
| Storm | #78909C#90A4AE | #0D0D1A#1A1A2E |
| Snow | #FFF9C4#FFFFFF | #1A237E#311B92 |
| Fog/Haze | #D7CCC8#EFEBE9 | #4E342E#5D4037 |
### 排版改进方案
1. **温度超大化**: 温度字号从 56-58px 提升到 64-72px基础组件形成视觉锚点
2. **层次分明**: 温度 → 天气状况 → 位置/指标,字号递减,透明度递减
3. **指标标签化**: 湿度/风速/AQI 用半透明圆角标签展示,而非纯文字
4. **预报芯片化**: 小时/每日预报用圆角半透明芯片卡片
5. **图标间距**: 天气图标与文字之间增加 8-12px 间距
---
## 文件变更清单
| 文件 | 操作 | 说明 |
|------|------|------|
| `Views/Components/MaterialWeatherVisualTheme.cs` | 修改 | 扩展 ResolvePalette 支持 styleId 分派新增4套风格配色 |
| `Views/Components/MaterialWeatherSceneControl.cs` | 修改 | 按 styleId 渲染不同背景风格(纯渐变/深色几何/清新波浪/暖色场景) |
| `Views/Components/WeatherWidgetBase.cs` | 修改 | 传递 styleId 到 SceneControl.Apply(),移除硬编码遮罩 |
| `Views/Components/WeatherWidget.axaml` | 修改 | 改进排版层次,移除硬编码遮罩 |
| `Views/Components/WeatherWidget.axaml.cs` | 修改 | 适配新排版 |
| `Views/Components/WeatherClockWidget.axaml` | 修改 | 改进排版,移除硬编码遮罩 |
| `Views/Components/WeatherClockWidget.axaml.cs` | 修改 | 适配新排版 |
| `Views/Components/ExtendedWeatherWidget.axaml` | 修改 | 改进排版,指标标签化,预报芯片化 |
| `Views/Components/ExtendedWeatherWidget.axaml.cs` | 修改 | 适配新排版+标签+芯片 |
| `Views/Components/HourlyWeatherWidget.axaml` | 修改 | 改进排版,预报芯片化 |
| `Views/Components/HourlyWeatherWidget.axaml.cs` | 修改 | 适配新排版+芯片 |
| `Views/Components/MultiDayWeatherWidget.axaml` | 修改 | 改进排版 |
| `Views/Components/MultiDayWeatherWidget.axaml.cs` | 修改 | 适配新排版 |
| `mocks/weather-widget-mock.html` | 新建 | HTML Mock 预览4种风格×2种天气×2种主题 |
---
## Task 分解
### Task 1: 创建 HTML Mock 预览
**Files:**
- Create: `mocks/weather-widget-mock.html`
- [ ] **Step 1: 创建 HTML Mock 文件**
创建完整的 HTML Mock包含
- 4 种风格Google / Geometric / Breezy / Lemon× 2 种天气(晴/雨)× 2 种主题(亮/暗)
- 每种风格展示基础天气组件(温度+状况+图标+位置)
- 改进后的排版:超大温度、层次分明、指标标签化
- 亮色/暗色主题切换按钮
- [ ] **Step 2: 在浏览器中打开 Mock 验证效果**
Run: `start mocks/weather-widget-mock.html`
---
### Task 2: 扩展 MaterialWeatherVisualTheme 支持多风格配色
**Files:**
- Modify: `LanMountainDesktop/Views/Components/MaterialWeatherVisualTheme.cs`
- [ ] **Step 1: 修改 ResolvePalette 方法签名**
`ResolvePalette(MaterialWeatherCondition condition, bool isNight)` 改为 `ResolvePalette(string? styleId, MaterialWeatherCondition condition, bool isNight)`,内部按 styleId 分派到不同配色方案。
- [ ] **Step 2: 新增 Google Weather 配色表**
为 GoogleWeatherV4 风格定义所有天气条件×昼夜的配色(参考上面配色方案设计章节)。
- [ ] **Step 3: 新增 Geometric 配色表**
为 Geometric 风格定义深色系配色。
- [ ] **Step 4: 新增 Breezy 配色表**
为 Breezy 风格定义清新渐变配色。
- [ ] **Step 5: 新增 Lemon 配色表**
为 LemonFlutter 风格定义暖色系配色。
- [ ] **Step 6: 更新所有调用点**
将所有 `ResolvePalette(condition, isNight)` 调用改为 `ResolvePalette(styleId, condition, isNight)`
---
### Task 3: 重构 MaterialWeatherSceneControl 支持多风格背景
**Files:**
- Modify: `LanMountainDesktop/Views/Components/MaterialWeatherSceneControl.cs`
- [ ] **Step 1: 扩展 Apply 方法签名**
`Apply(MaterialWeatherCondition condition, MaterialWeatherPalette palette, bool isLive)` 改为 `Apply(string? styleId, MaterialWeatherCondition condition, MaterialWeatherPalette palette, bool isLive)`,存储 styleId。
- [ ] **Step 2: 实现 Google Weather 风格渲染**
纯渐变背景,无几何装饰。背景使用 palette 的 BackgroundTop→BackgroundBottom 渐变。仅保留天气特效(雨滴/雪花/雾线)。
- [ ] **Step 3: 实现 Geometric 风格渲染**
深色渐变 + 大面积半透明几何圆形叠加。在基础渐变上叠加 2-3 个大椭圆(使用 palette 的 PrimaryShape/SecondaryShape/AccentShape营造深度感。保留天气特效。
- [ ] **Step 4: 实现 Breezy 风格渲染**
清新渐变 + 柔和波浪线条。在基础渐变上绘制 2-3 条正弦波浪线(使用 palette 的 SurfaceTint营造微风感。保留天气特效。
- [ ] **Step 5: 实现 Lemon 风格渲染**
暖色渐变 + 天气场景装饰。晴天绘制太阳光芒(放射线),多云绘制云朵轮廓,雨天绘制雨丝。保留天气特效。
- [ ] **Step 6: 更新所有调用点**
将所有 `SceneControl.Apply(condition, palette, isLive)` 改为 `SceneControl.Apply(styleId, condition, palette, isLive)`
---
### Task 4: 更新 WeatherWidgetBase 传递 styleId
**Files:**
- Modify: `LanMountainDesktop/Views/Components/WeatherWidgetBase.cs`
- [ ] **Step 1: 修改 ApplyCurrentScene 方法**
`ApplyCurrentScene()` 中将 `CurrentVisualStyleId` 传递给 `SceneControl.Apply()`
- [ ] **Step 2: 修改 ApplySnapshot 中的 ResolvePalette 调用**
`MaterialWeatherVisualTheme.ResolvePalette(CurrentCondition, isNight)` 改为 `MaterialWeatherVisualTheme.ResolvePalette(CurrentVisualStyleId, CurrentCondition, isNight)`
---
### Task 5: 改进各天气 Widget 的 XAML 排版
**Files:**
- Modify: `WeatherWidget.axaml` — 移除硬编码遮罩 `<Border Background="#30FFFFFF" />`,改用 palette 驱动的半透明遮罩
- Modify: `WeatherClockWidget.axaml` — 同上
- Modify: `ExtendedWeatherWidget.axaml` — 同上 + 指标区域改用标签样式
- Modify: `HourlyWeatherWidget.axaml` — 同上 + 预报区域改用芯片样式
- Modify: `MultiDayWeatherWidget.axaml` — 同上
- [ ] **Step 1: 移除所有硬编码遮罩**
`<Border Background="#30FFFFFF" />` / `#42FFFFFF` / `#34FFFFFF` / `#38FFFFFF` / `#3CFFFFFF` 替换为 `<Border x:Name="OverlayBorder" />`,在 code-behind 中根据 palette 设置遮罩颜色。
- [ ] **Step 2: 改进 WeatherWidget 排版**
增大温度字号58→64增加图标与文字间距调整位置文字透明度。
- [ ] **Step 3: 改进 WeatherClockWidget 排版**
增大时钟字号,增加天气信息与时间间距。
- [ ] **Step 4: 改进 ExtendedWeatherWidget 排版**
指标用半透明圆角标签,小时/每日预报用圆角芯片卡片。
- [ ] **Step 5: 改进 HourlyWeatherWidget 排版**
预报区域用圆角芯片卡片样式。
- [ ] **Step 6: 改进 MultiDayWeatherWidget 排版**
每日预报行增加分隔线和更好的间距。
---
### Task 6: 更新各天气 Widget 的 code-behind
**Files:**
- Modify: 所有天气 Widget 的 `.axaml.cs` 文件
- [ ] **Step 1: 更新 WeatherWidget.axaml.cs**
- 设置 OverlayBorder 背景
- 增大温度字号
- 适配新排版参数
- [ ] **Step 2: 更新 WeatherClockWidget.axaml.cs**
- 设置 OverlayBorder 背景
- 适配新排版
- [ ] **Step 3: 更新 ExtendedWeatherWidget.axaml.cs**
- 设置 OverlayBorder 背景
- 指标标签化CreateMetric 改为带圆角背景的标签)
- 预报芯片化
- [ ] **Step 4: 更新 HourlyWeatherWidget.axaml.cs**
- 设置 OverlayBorder 背景
- 预报芯片化CreateChip 改为带圆角背景的芯片)
- [ ] **Step 5: 更新 MultiDayWeatherWidget.axaml.cs**
- 设置 OverlayBorder 背景
- 适配新排版
---
### Task 7: 验证与测试
- [ ] **Step 1: 运行项目查看效果**
Run: `dotnet run --project LanMountainDesktop/LanMountainDesktop.csproj`
- [ ] **Step 2: 运行相关测试**
Run: `dotnet test LanMountainDesktop.slnx -c Debug`
- [ ] **Step 3: 检查圆角规范合规**
确认所有组件 RootBorder 使用 `DesignCornerRadiusComponent`,新增的标签/芯片使用 `DesignCornerRadiusSm`/`DesignCornerRadiusMd`
---
## 假设与决策
1. **4 套独立风格**: 每种图标风格对应独立的背景配色和装饰风格,切换图标风格时背景也跟着变
2. **配色表驱动**: 所有颜色定义在 `MaterialWeatherVisualTheme` 中,不硬编码到 SceneControl
3. **保留天气特效**: 雨滴/雪花/雾线/闪电等天气特效在所有风格中保留,但颜色跟随 palette
4. **遮罩动态化**: 半透明遮罩颜色从 palette 中派生,而非硬编码 `#30FFFFFF`
5. **排版渐进改进**: 不做大规模 XAML 重构,而是在现有结构上优化字号/间距/透明度
6. **数据层不变**: WeatherSnapshot、WeatherIconAssetResolver、WeatherWidgetBase 的数据逻辑不变
7. **接口兼容**: IDesktopComponentWidget 等接口实现不变
## 验证步骤
1. HTML Mock 在浏览器中展示 4 种风格效果满意
2. Avalonia 项目编译通过
3. 运行项目,切换图标风格时背景配色和装饰风格跟着变化
4. 亮色/暗色主题切换正常
5. 5 个天气组件排版层次分明
6. 指标标签化和预报芯片化正常显示
7. 测试通过