mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
feat.淡入淡出动画。
This commit is contained in:
117
.trae/documents/skeleton-screen-plan.md
Normal file
117
.trae/documents/skeleton-screen-plan.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# 骨架页(Skeleton Screen)实施计划
|
||||
|
||||
## 问题分析
|
||||
|
||||
当前首次启动时,用户看到的现象:
|
||||
|
||||
1. 全屏窗口立即显示,但状态栏组件全部 `IsVisible="False"`(空白)
|
||||
2. 头像区域只有 fallback 文字 "U",尺寸未计算(显得巨大)
|
||||
3. 底部 Dock 任务栏已经渲染但内容为空
|
||||
4. 壁纸加载完成前,桌面区域是透明/黑色的
|
||||
5. 整体看起来就是一个"Dock 栏覆盖全屏 + 巨大头像"的半成品状态
|
||||
|
||||
**根本原因**:`OnOpened` 中有大量同步初始化操作(壁纸解码、组件布局、启动器扫描等),在它们完成之前,UI 元素要么不可见要么处于默认状态。
|
||||
|
||||
## 方案概述
|
||||
|
||||
在 `DesktopPage` 层添加一个**骨架遮罩层**,覆盖在真实内容之上,在初始化完成前显示骨架占位,初始化完成后淡出消失。
|
||||
|
||||
### 骨架页布局
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ [状态栏骨架] │
|
||||
│ ┌─────────┐ ┌──────────────────┐ ┌─────────┐ │
|
||||
│ │ ○ 头像 │ │ ████ 时钟 ████ │ │ ○ ○ │ │
|
||||
│ └─────────┘ └──────────────────┘ └─────────┘ │
|
||||
│ │
|
||||
│ (桌面区域 - 壁纸层) │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ [Dock 任务栏骨架] │ │
|
||||
│ │ ██ ████████ ████████ ████████ ████████ ○ │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 骨架元素
|
||||
|
||||
| 区域 | 骨架元素 | 形状 | 说明 |
|
||||
| ------- | ------ | ----------------------------------- | ----------------------------- |
|
||||
| 状态栏-中间 | 时钟骨架 | 圆角矩形(`DesignCornerRadiusComponent`) | 模拟 ClockWidget 的胶囊形状 |
|
||||
| 状态栏-中间 | 文本胶囊骨架 | 圆角矩形(较小) | 模拟 TextCapsuleWidget |
|
||||
| 底部 Dock | 头像骨架 | 圆形 | 模拟 TaskbarProfileAvatarBorder |
|
||||
| 底部 Dock | 操作按钮骨架 | 圆角矩形 | 模拟任务栏按钮 |
|
||||
| 底部 Dock | 分隔线骨架 | 细长矩形 | 模拟按钮间分隔 |
|
||||
|
||||
### 骨架样式
|
||||
|
||||
* **颜色**:使用 `AdaptiveGlassPanelBackgroundBrush` 作为基础色,叠加一个 **Shimmer 动画**(微光扫过效果)
|
||||
|
||||
* **圆角**:与真实组件一致,使用 `DesignCornerRadiusComponent`
|
||||
|
||||
* **动画**:Shimmer 微光从左到右扫过,周期 2s,使用 `FluttermotionToken` 缓动
|
||||
|
||||
## 实施步骤
|
||||
|
||||
### Step 1: 创建 Shimmer 动画画刷
|
||||
|
||||
在 `GlassModule.axaml` 或新建 `SkeletonStyles.axaml` 中定义:
|
||||
|
||||
* 创建 `ShimmerBrush`:一个 `LinearGradientBrush`,包含高光条带
|
||||
|
||||
* 创建 `ShimmerAnimation` storyboard:让高光条带从左到右移动
|
||||
|
||||
* 定义 `skeleton-shimmer` 样式类:应用 ShimmerBrush + 动画
|
||||
|
||||
### Step 2: 在 MainWindow\.axaml 中添加骨架遮罩层
|
||||
|
||||
在 `DesktopPage` Grid 内、所有真实内容之上添加一个 `Grid x:Name="SkeletonOverlay"`:
|
||||
|
||||
* 初始 `IsVisible="True"`,`ZIndex="999"`
|
||||
|
||||
* 包含状态栏骨架区域和底部 Dock 骨架区域
|
||||
|
||||
* 使用与真实布局相同的 Grid RowDefinitions,确保骨架元素对齐
|
||||
|
||||
### Step 3: 在 MainWindow\.axaml.cs 中控制骨架显示/隐藏
|
||||
|
||||
* 在 `OnOpened` 开始时,骨架层可见
|
||||
|
||||
* 在 `OnOpened` 末尾(所有初始化完成后),调用 `HideSkeletonOverlayAsync()`
|
||||
|
||||
* `HideSkeletonOverlayAsync()`:播放淡出动画 → 设置 `IsVisible="False"`
|
||||
|
||||
* 如果启用了滑入滑出过渡,骨架层在入场动画期间也应可见,入场动画完成后再淡出
|
||||
|
||||
### Step 4: 骨架元素尺寸适配
|
||||
|
||||
* 骨架元素需要在 `ApplyTaskbarSettings()` 后更新尺寸(因为 `taskbarCellHeight` 等值在 OnOpened 中才计算)
|
||||
|
||||
* 或者在 XAML 中使用相对尺寸(百分比/比例),避免依赖代码计算
|
||||
|
||||
### Step 5: 与窗口过渡动画的协调
|
||||
|
||||
* 入场动画(`PrepareEnterAnimation` / `PlayEnterAnimation`)期间,骨架层应保持可见
|
||||
|
||||
* 入场动画完成后,先短暂显示骨架(\~100ms),然后淡出骨架
|
||||
|
||||
* 退场动画时,无需特殊处理(骨架已隐藏)
|
||||
|
||||
## 涉及文件
|
||||
|
||||
| 文件 | 改动类型 |
|
||||
| --------------------------------- | -------------------- |
|
||||
| `Styles/SkeletonStyles.axaml`(新建) | Shimmer 画刷 + 骨架样式类 |
|
||||
| `Views/MainWindow.axaml` | 添加 SkeletonOverlay 层 |
|
||||
| `Views/MainWindow.axaml.cs` | 骨架显示/隐藏逻辑 |
|
||||
| `App.axaml` | 引入 SkeletonStyles 资源 |
|
||||
|
||||
## 不涉及的文件
|
||||
|
||||
* 不修改组件代码(ClockWidget、TextCapsuleWidget 等)
|
||||
|
||||
* 不修改设置系统
|
||||
|
||||
* 不修改 App.axaml.cs 的启动流程
|
||||
|
||||
Reference in New Issue
Block a user