Files
LanMountainDesktop/.trae/specs/window-slide-transition/spec.md
2026-04-15 10:49:04 +08:00

139 lines
6.6 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.
# 窗口过渡动画 Spec
## Why
当前全屏窗口在"回到 Windows"(最小化)和"恢复应用"时存在严重的视觉问题:
1. 恢复时经历 `Minimized → Normal → FullScreen` 两步跳变,用户会短暂看到无框小窗口
2. 状态切换无任何过渡动画,体验生硬
3. `OnWindowPropertyChanged` 使用 `Dispatcher.UIThread.Post` 延迟纠正,进一步延长了 Normal 中间态的可见时间
## What Changes
-`MainWindow.axaml``DesktopPage` 上添加 `TranslateTransform``TranslateTransform.X` 过渡动画
- 修改 `MainWindow.axaml.cs``OnMinimizeClick`,实现退场动画(滑出/淡出 → 最小化)
- 修改 `App.axaml.cs``RestoreOrCreateMainWindow`,实现入场动画(全屏 → 滑入/淡入)
- 修改 `MainWindow.axaml.cs``OnWindowPropertyChanged`,在动画期间暂停强制全屏逻辑
-`AppSettingsSnapshot` 中添加 `EnableSlideTransition` 设置项(默认关闭)
-`GeneralSettingsPageViewModel` 中添加对应 ViewModel 属性
-`GeneralSettingsPage.axaml` 中添加开关 UI仅 Windows 平台显示)
- 添加平台检测逻辑Windows 且开启设置时使用滑入滑出,其他情况使用 Opacity 淡入淡出
## Impact
- Affected specs: 窗口生命周期过渡动画
- Affected code:
- `LanMountainDesktop/Views/MainWindow.axaml` - DesktopPage 添加 TranslateTransform
- `LanMountainDesktop/Views/MainWindow.axaml.cs` - OnMinimizeClick、OnWindowPropertyChanged、新增动画方法
- `LanMountainDesktop/App.axaml.cs` - RestoreOrCreateMainWindow、OnMainWindowPropertyChanged
- `LanMountainDesktop/Models/AppSettingsSnapshot.cs` - 新增 EnableSlideTransition 字段
- `LanMountainDesktop/ViewModels/SettingsViewModels.cs` - GeneralSettingsPageViewModel 新增属性
- `LanMountainDesktop/Views/SettingsPages/GeneralSettingsPage.axaml` - 新增开关 UI
---
## ADDED Requirements
### Requirement: 窗口退场过渡动画
系统 SHALL 在主窗口最小化/隐藏时播放退场过渡动画,消除窗口状态跳变的视觉闪烁。
#### Scenario: Opacity 淡出退场(所有平台默认)
- **WHEN** 用户点击"回到 Windows"或触发最小化
- **THEN** 系统将 `DesktopPage.Opacity` 设为 0触发淡出动画
- **AND THEN** 动画完成后执行 `WindowState = Minimized`
- **AND THEN** 最小化完成后重置 `DesktopPage.Opacity = 1`(窗口已不可见)
#### Scenario: 滑出退场Windows + 开启设置)
- **WHEN** 用户点击"回到 Windows"且运行在 Windows 平台且已开启滑入滑出设置
- **THEN** 系统同时将 `DesktopPage.Opacity` 设为 0 且 `DesktopPageSlideTransform.X` 设为屏幕宽度
- **AND THEN** 动画完成后执行 `WindowState = Minimized`
- **AND THEN** 最小化完成后重置 `DesktopPageSlideTransform.X = 0``DesktopPage.Opacity = 1`
### Requirement: 窗口入场过渡动画
系统 SHALL 在主窗口恢复时播放入场过渡动画,消除 Normal 中间态的视觉闪烁。
#### Scenario: Opacity 淡入入场(所有平台默认)
- **WHEN** 主窗口从最小化/隐藏状态恢复
- **THEN** 系统先将 `DesktopPage.Opacity` 设为 0遮住 Normal 中间态)
- **AND THEN** 完成 `Minimized → Normal → FullScreen` 状态切换
- **AND THEN** 等 FullScreen 状态生效后将 `DesktopPage.Opacity` 设为 1触发淡入动画
#### Scenario: 滑入入场Windows + 开启设置)
- **WHEN** 主窗口从最小化/隐藏状态恢复且运行在 Windows 平台且已开启滑入滑出设置
- **THEN** 系统先将 `DesktopPage.Opacity` 设为 0 且 `DesktopPageSlideTransform.X` 设为屏幕宽度
- **AND THEN** 完成 `Minimized → Normal → FullScreen` 状态切换
- **AND THEN** 等 FullScreen 状态生效后同时将 `DesktopPage.Opacity` 设为 1 且 `DesktopPageSlideTransform.X` 设为 0触发滑入+淡入组合动画
### Requirement: 动画期间交互保护
系统 SHALL 在过渡动画播放期间防止用户交互和状态冲突。
#### Scenario: 动画期间禁止交互
- **WHEN** 退场或入场动画正在播放
- **THEN** `DesktopPage.IsHitTestVisible` 设为 `false`
- **AND THEN** 动画完成后恢复为 `true`
#### Scenario: 动画期间暂停强制全屏
- **WHEN** 入场动画正在播放且窗口临时处于 Normal 状态
- **THEN** `OnWindowPropertyChanged` 不执行强制全屏纠正
- **AND THEN** 入场动画完成后恢复正常强制全屏逻辑
#### Scenario: 防止快速连续操作
- **WHEN** 用户在动画播放期间再次触发最小化或恢复
- **THEN** 系统忽略重复操作,避免动画冲突
### Requirement: 滑入滑出设置项
系统 SHALL 在基本设置页面提供"滑入滑出过渡效果"开关,仅 Windows 平台可见。
#### Scenario: 设置项可见性
- **WHEN** 用户在 Windows 平台打开基本设置页面
- **THEN** 显示"滑入滑出过渡效果"开关
- **WHEN** 用户在非 Windows 平台打开基本设置页面
- **THEN** 不显示该开关
#### Scenario: 设置项默认值
- **WHEN** 用户首次安装应用
- **THEN** `EnableSlideTransition` 默认为 `false`
#### Scenario: 设置持久化
- **WHEN** 用户切换"滑入滑出过渡效果"开关
- **THEN** 设置值立即持久化到 `AppSettingsSnapshot.EnableSlideTransition`
- **AND THEN** 下次窗口过渡时立即生效,无需重启
### Requirement: DesktopPage TranslateTransform 声明
系统 SHALL 在 `DesktopPage` 上声明 `TranslateTransform` 和对应的过渡动画。
#### Scenario: XAML 声明
- **WHEN** MainWindow 初始化
- **THEN** `DesktopPage` 拥有名为 `DesktopPageSlideTransform``TranslateTransform`
- **AND THEN** `DesktopPage.Transitions` 包含 `Opacity``TranslateTransform.X` 两个过渡
- **AND THEN** 过渡时长使用 `FluttermotionToken.Duration.Page`320ms`FluttermotionToken.Duration.Intro`400ms
- **AND THEN** 缓动函数使用 `0.05,0.75,0.10,1.00`DecelerateBezier
## MODIFIED Requirements
### Requirement: OnMinimizeClick 行为
**当前**: 直接设置 `WindowState = WindowState.Minimized`,无动画
**修改后**: 先播放退场动画,动画完成后再设置 `WindowState = WindowState.Minimized`
### Requirement: RestoreOrCreateMainWindow 行为
**当前**: `Show() → Normal → FullScreen`,无过渡动画,用户可见 Normal 中间态
**修改后**: 先将 `DesktopPage` 设为不可见Opacity=0 + 可选滑出位),再执行状态切换,最后播放入场动画
### Requirement: OnWindowPropertyChanged 强制全屏逻辑
**当前**: 任何非 Minimized/FullScreen 状态立即纠正为 FullScreen
**修改后**: 动画期间允许临时 Normal 状态存在,动画完成后恢复强制全屏逻辑
## REMOVED Requirements
无移除的需求。