动画优化
This commit is contained in:
lincube
2026-03-05 14:03:35 +08:00
parent 2e49602bff
commit d182925b58
8 changed files with 375 additions and 85 deletions

View File

@@ -16,7 +16,7 @@ using LanMountainDesktop.Services;
namespace LanMountainDesktop.Views.Components;
public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
public partial class WeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
{
private enum WeatherVisualKind
{
@@ -93,6 +93,8 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
private readonly List<Border> _particleVisuals = new();
private readonly List<ParticleState> _particleStates = new();
private readonly Random _particleRandom = new();
private readonly ScaleTransform _backgroundMotionScaleTransform = new(1, 1);
private readonly TranslateTransform _backgroundMotionTranslateTransform = new();
private IWeatherInfoService _weatherInfoService = DefaultWeatherInfoService;
private TimeZoneService? _timeZoneService;
@@ -104,11 +106,13 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
private double _animationPhase;
private int _activeParticleCount;
private bool _isAttached;
private bool _isOnActivePage = true;
private bool _isRefreshing;
public WeatherWidget()
{
InitializeComponent();
InitializeMotionTransform();
_refreshTimer.Tick += OnRefreshTimerTick;
_backgroundAnimationTimer.Tick += OnBackgroundAnimationTick;
@@ -143,7 +147,20 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
{
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;
if (_isAttached)
if (_isAttached && _isOnActivePage)
{
_ = RefreshWeatherAsync(forceRefresh: false);
}
}
public void SetDesktopPageContext(bool isOnActivePage, bool isEditMode)
{
_ = isEditMode;
var wasOnActivePage = _isOnActivePage;
_isOnActivePage = isOnActivePage;
UpdateTimerState();
if (!wasOnActivePage && _isOnActivePage && _isAttached)
{
_ = RefreshWeatherAsync(forceRefresh: false);
}
@@ -176,16 +193,17 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
_isAttached = true;
_refreshTimer.Start();
_backgroundAnimationTimer.Start();
_ = RefreshWeatherAsync(forceRefresh: false);
UpdateTimerState();
if (_isOnActivePage)
{
_ = RefreshWeatherAsync(forceRefresh: false);
}
}
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
_isAttached = false;
_refreshTimer.Stop();
_backgroundAnimationTimer.Stop();
UpdateTimerState();
CancelRefreshRequest();
}
@@ -202,7 +220,7 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
private void OnBackgroundAnimationTick(object? sender, EventArgs e)
{
if (!_isAttached)
if (!_isAttached || !_isOnActivePage)
{
return;
}
@@ -265,7 +283,7 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
private async Task RefreshWeatherAsync(bool forceRefresh)
{
if (!_isAttached || _isRefreshing)
if (!_isAttached || !_isOnActivePage || _isRefreshing)
{
return;
}
@@ -980,15 +998,43 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
private void SetMotionTransform(double translateX, double translateY, double scale)
{
var group = new TransformGroup
_backgroundMotionScaleTransform.ScaleX = scale;
_backgroundMotionScaleTransform.ScaleY = scale;
_backgroundMotionTranslateTransform.X = translateX;
_backgroundMotionTranslateTransform.Y = translateY;
}
private void InitializeMotionTransform()
{
BackgroundMotionLayer.RenderTransform = new TransformGroup
{
Children = new Transforms
{
new ScaleTransform(scale, scale),
new TranslateTransform(translateX, translateY)
_backgroundMotionScaleTransform,
_backgroundMotionTranslateTransform
}
};
BackgroundMotionLayer.RenderTransform = group;
}
private void UpdateTimerState()
{
if (_isAttached && _isOnActivePage)
{
if (!_refreshTimer.IsEnabled)
{
_refreshTimer.Start();
}
if (!_backgroundAnimationTimer.IsEnabled)
{
_backgroundAnimationTimer.Start();
}
return;
}
_refreshTimer.Stop();
_backgroundAnimationTimer.Stop();
}
private void InitializeParticleVisuals()