feat.淡入淡出动画。

This commit is contained in:
lincube
2026-04-15 10:49:04 +08:00
parent 9c529f2992
commit c2cc62b58b
11 changed files with 498 additions and 4 deletions

View File

@@ -566,13 +566,14 @@ public partial class App : Application
try
{
// 先隐藏透明覆盖层窗口
if (_transparentOverlayWindow is not null && _transparentOverlayWindow.IsVisible)
{
_transparentOverlayWindow.Hide();
}
var mainWindow = GetOrCreateMainWindow(desktop, source);
mainWindow.PrepareEnterAnimation();
mainWindow.ShowInTaskbar = true;
if (!mainWindow.IsVisible)
@@ -593,6 +594,12 @@ public partial class App : Application
mainWindow.Activate();
mainWindow.Topmost = true;
mainWindow.Topmost = false;
Dispatcher.UIThread.Post(() =>
{
mainWindow.PlayEnterAnimation();
}, DispatcherPriority.Background);
SetDesktopShellState(DesktopShellState.ForegroundDesktop, $"Restore:{source}");
AppLogger.Info(
"DesktopShell",

View File

@@ -152,6 +152,8 @@ public sealed class AppSettingsSnapshot
public bool EnableThreeFingerSwipe { get; set; } = false;
public bool EnableSlideTransition { get; set; } = false;
public bool EnableFusedDesktop { get; set; } = false;
public List<string> DisabledPluginIds { get; set; } = [];

View File

@@ -201,6 +201,7 @@ public sealed partial class GeneralSettingsPageViewModel : ViewModelBase, IDispo
SelectedRenderMode = RenderModes.FirstOrDefault(option =>
string.Equals(option.Value, normalizedRenderMode, StringComparison.OrdinalIgnoreCase))
?? RenderModes[0];
EnableSlideTransition = appSnapshot.EnableSlideTransition;
_isInitializing = false;
RefreshPreview();
@@ -232,6 +233,11 @@ public sealed partial class GeneralSettingsPageViewModel : ViewModelBase, IDispo
{
return;
}
if (changedKeys.Contains(nameof(AppSettingsSnapshot.EnableSlideTransition)))
{
EnableSlideTransition = _settingsFacade.Settings.LoadSnapshot<AppSettingsSnapshot>(SettingsScope.App).EnableSlideTransition;
}
}
public event Action? RestartRequested;
@@ -251,6 +257,11 @@ public sealed partial class GeneralSettingsPageViewModel : ViewModelBase, IDispo
[ObservableProperty]
private SelectionOption _selectedRenderMode = new(AppRenderingModeHelper.Default, "Default");
[ObservableProperty]
private bool _enableSlideTransition;
public bool IsSlideTransitionAvailable => System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows);
[ObservableProperty]
private string _pageTitle = string.Empty;
@@ -350,6 +361,24 @@ public sealed partial class GeneralSettingsPageViewModel : ViewModelBase, IDispo
}
}
partial void OnEnableSlideTransitionChanged(bool value)
{
if (_isInitializing) return;
SaveField(nameof(AppSettingsSnapshot.EnableSlideTransition), value);
}
private void SaveField<T>(string key, T value)
{
var snapshot = _settingsFacade.Settings.LoadSnapshot<AppSettingsSnapshot>(SettingsScope.App);
var property = typeof(AppSettingsSnapshot).GetProperty(key);
if (property is not null && property.CanWrite)
{
property.SetValue(snapshot, value);
}
_settingsFacade.Settings.SaveSnapshot(SettingsScope.App, snapshot, changedKeys: [key]);
}
private IReadOnlyList<SelectionOption> CreateLanguageOptions()
{
return

View File

@@ -77,7 +77,9 @@ public partial class MainWindow
string.Equals(key, nameof(AppSettingsSnapshot.UpdateChannel), StringComparison.OrdinalIgnoreCase) ||
string.Equals(key, nameof(AppSettingsSnapshot.UpdateMode), StringComparison.OrdinalIgnoreCase) ||
string.Equals(key, nameof(AppSettingsSnapshot.UpdateDownloadSource), StringComparison.OrdinalIgnoreCase) ||
string.Equals(key, nameof(AppSettingsSnapshot.UpdateDownloadThreads), StringComparison.OrdinalIgnoreCase)))
string.Equals(key, nameof(AppSettingsSnapshot.UpdateDownloadThreads), StringComparison.OrdinalIgnoreCase) ||
string.Equals(key, nameof(AppSettingsSnapshot.EnableThreeFingerSwipe), StringComparison.OrdinalIgnoreCase) ||
string.Equals(key, nameof(AppSettingsSnapshot.EnableSlideTransition), StringComparison.OrdinalIgnoreCase)))
{
return;
}

View File

@@ -98,9 +98,13 @@
<Grid x:Name="DesktopPage"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.Transitions>
<Transitions>
<DoubleTransition Property="Opacity" Duration="{StaticResource FluttermotionToken.Duration.Page}" />
<DoubleTransition Property="Opacity" Duration="{StaticResource FluttermotionToken.Duration.Page}" Easing="0.05,0.75,0.10,1.00" />
<DoubleTransition Property="TranslateTransform.X" Duration="{StaticResource FluttermotionToken.Duration.Intro}" Easing="0.05,0.75,0.10,1.00" />
</Transitions>
</Grid.Transitions>

View File

@@ -132,6 +132,8 @@ public partial class MainWindow : Window, ISettingsWindowAnchorProvider
private double _currentDesktopCellGap;
private double _currentDesktopEdgeInset;
private string _gridSpacingPreset = "Relaxed";
private bool _isSlideAnimationActive;
private TranslateTransform? _desktopPageSlideTransform;
private string _statusBarSpacingMode = "Relaxed";
private int _statusBarCustomSpacingPercent = 12;
private bool _statusBarClockTransparentBackground;
@@ -833,7 +835,103 @@ public partial class MainWindow : Window, ISettingsWindowAnchorProvider
private void OnMinimizeClick(object? sender, RoutedEventArgs e)
{
if (_isSlideAnimationActive)
{
return;
}
SlideOutAndMinimizeAsync();
}
private TranslateTransform GetDesktopPageSlideTransform()
{
if (_desktopPageSlideTransform is not null)
{
return _desktopPageSlideTransform;
}
_desktopPageSlideTransform = DesktopPage.RenderTransform as TranslateTransform;
if (_desktopPageSlideTransform is null)
{
_desktopPageSlideTransform = new TranslateTransform();
DesktopPage.RenderTransform = _desktopPageSlideTransform;
}
return _desktopPageSlideTransform;
}
private async void SlideOutAndMinimizeAsync()
{
_isSlideAnimationActive = true;
DesktopPage.IsHitTestVisible = false;
var useSlide = IsSlideTransitionEnabled();
var slideTransform = GetDesktopPageSlideTransform();
if (useSlide)
{
slideTransform.X = Bounds.Width;
}
DesktopPage.Opacity = 0;
await Task.Delay(useSlide
? FluttermotionToken.Intro
: FluttermotionToken.Page);
if (!_isSlideAnimationActive)
{
return;
}
WindowState = WindowState.Minimized;
slideTransform.X = 0;
DesktopPage.Opacity = 1;
DesktopPage.IsHitTestVisible = true;
_isSlideAnimationActive = false;
}
public void PrepareEnterAnimation()
{
_isSlideAnimationActive = false;
var useSlide = IsSlideTransitionEnabled();
var slideTransform = GetDesktopPageSlideTransform();
var savedTransitions = DesktopPage.Transitions;
DesktopPage.Transitions = null;
DesktopPage.Opacity = 0;
if (useSlide)
{
slideTransform.X = Bounds.Width > 0 ? Bounds.Width : 1920;
}
DesktopPage.Transitions = savedTransitions;
DesktopPage.IsHitTestVisible = false;
_isSlideAnimationActive = true;
}
public void PlayEnterAnimation()
{
var slideTransform = GetDesktopPageSlideTransform();
DesktopPage.Opacity = 1;
slideTransform.X = 0;
DesktopPage.IsHitTestVisible = true;
_isSlideAnimationActive = false;
}
private bool IsSlideTransitionEnabled()
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return false;
}
var snapshot = _settingsService.LoadSnapshot<AppSettingsSnapshot>(SettingsScope.App);
return snapshot.EnableSlideTransition;
}
private void OnWindowPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
@@ -848,8 +946,18 @@ public partial class MainWindow : Window, ISettingsWindowAnchorProvider
return;
}
if (_isSlideAnimationActive)
{
return;
}
Dispatcher.UIThread.Post(() =>
{
if (_isSlideAnimationActive)
{
return;
}
if (WindowState is not (WindowState.Minimized or WindowState.FullScreen))
{
WindowState = WindowState.FullScreen;

View File

@@ -106,6 +106,17 @@
</ui:SettingsExpanderItem>
</ui:SettingsExpander>
<ui:SettingsExpander Header="滑入滑出过渡效果"
Description="启用后,进入和退出桌面时使用滑入滑出动画(仅 Windows"
IsVisible="{Binding IsSlideTransitionAvailable}">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="ArrowRight" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer>
<ToggleSwitch IsChecked="{Binding EnableSlideTransition}" />
</ui:SettingsExpander.Footer>
</ui:SettingsExpander>
</StackPanel>
</ScrollViewer>
</UserControl>