diff --git a/MapControl/Avalonia/OpacityHelper.Avalonia.cs b/MapControl/Avalonia/OpacityHelper.Avalonia.cs
new file mode 100644
index 00000000..b0c59cbe
--- /dev/null
+++ b/MapControl/Avalonia/OpacityHelper.Avalonia.cs
@@ -0,0 +1,59 @@
+// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
+// Copyright © 2024 Clemens Fischer
+// Licensed under the Microsoft Public License (Ms-PL)
+
+using System.Threading.Tasks;
+using System;
+using Avalonia.Controls;
+using Avalonia.Animation;
+using Avalonia.Styling;
+using System.Xml.Linq;
+
+namespace MapControl
+{
+ public static class OpacityHelper
+ {
+ public static Task FadeIn(Control element)
+ {
+ var animation = new Animation
+ {
+ Duration = MapBase.ImageFadeDuration,
+ Children =
+ {
+ new KeyFrame
+ {
+ KeyTime = TimeSpan.Zero,
+ Setters = { new Setter(Visual.OpacityProperty, 0d) }
+ },
+ new KeyFrame
+ {
+ KeyTime = MapBase.ImageFadeDuration,
+ Setters = { new Setter(Visual.OpacityProperty, 1d) }
+ }
+ }
+ };
+
+ return animation.RunAsync(element);
+ }
+
+ public static async Task SwapOpacities(Control topElement, Control bottomElement)
+ {
+ var animation = new Animation
+ {
+ Duration = MapBase.ImageFadeDuration,
+ Children =
+ {
+ new KeyFrame
+ {
+ KeyTime = MapBase.ImageFadeDuration,
+ Setters = { new Setter(Visual.OpacityProperty, 1d) }
+ }
+ }
+ };
+
+ await animation.RunAsync(topElement);
+
+ bottomElement.Opacity = 0d;
+ }
+ }
+}
diff --git a/MapControl/Avalonia/Tile.Avalonia.cs b/MapControl/Avalonia/Tile.Avalonia.cs
index 46245212..23e313f8 100644
--- a/MapControl/Avalonia/Tile.Avalonia.cs
+++ b/MapControl/Avalonia/Tile.Avalonia.cs
@@ -2,35 +2,13 @@
// Copyright © 2024 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
-using Avalonia.Animation;
-using Avalonia.Styling;
-using System;
-
namespace MapControl
{
public partial class Tile
{
private void AnimateImageOpacity()
{
- var animation = new Animation
- {
- Duration = MapBase.ImageFadeDuration,
- Children =
- {
- new KeyFrame
- {
- KeyTime = TimeSpan.Zero,
- Setters = { new Setter(Visual.OpacityProperty, 0d) }
- },
- new KeyFrame
- {
- KeyTime = MapBase.ImageFadeDuration,
- Setters = { new Setter(Visual.OpacityProperty, 1d) }
- }
- }
- };
-
- _ = animation.RunAsync(Image);
+ _ = OpacityHelper.FadeIn(Image);
}
}
}
diff --git a/MapControl/Shared/MapImageLayer.cs b/MapControl/Shared/MapImageLayer.cs
index 5c9a47ac..13333e9e 100644
--- a/MapControl/Shared/MapImageLayer.cs
+++ b/MapControl/Shared/MapImageLayer.cs
@@ -17,19 +17,16 @@ using Windows.Foundation;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
-using Microsoft.UI.Xaml.Media.Animation;
using DispatcherTimer = Microsoft.UI.Dispatching.DispatcherQueueTimer;
#elif UWP
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
-using Windows.UI.Xaml.Media.Animation;
#else
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
-using System.Windows.Media.Animation;
using System.Windows.Threading;
#endif
@@ -209,7 +206,7 @@ namespace MapControl
}
}
- SwapImages(image, boundingBox);
+ await SwapImages(image, boundingBox);
updateInProgress = false;
}
@@ -241,7 +238,7 @@ namespace MapControl
}
}
- private void SwapImages(ImageSource image, BoundingBox boundingBox)
+ private async Task SwapImages(ImageSource image, BoundingBox boundingBox)
{
if (Children.Count >= 2)
{
@@ -254,21 +251,7 @@ namespace MapControl
topImage.Source = image;
SetBoundingBox(topImage, boundingBox);
-#if AVALONIA
-#else
- topImage.BeginAnimation(OpacityProperty, new DoubleAnimation
- {
- To = 1d,
- Duration = MapBase.ImageFadeDuration
- });
-
- bottomImage.BeginAnimation(OpacityProperty, new DoubleAnimation
- {
- To = 0d,
- BeginTime = MapBase.ImageFadeDuration,
- Duration = TimeSpan.Zero
- });
-#endif
+ await OpacityHelper.SwapOpacities(topImage, bottomImage);
}
}
}
diff --git a/MapControl/UWP/MapControl.UWP.csproj b/MapControl/UWP/MapControl.UWP.csproj
index 6c7ea0c3..d1e71c09 100644
--- a/MapControl/UWP/MapControl.UWP.csproj
+++ b/MapControl/UWP/MapControl.UWP.csproj
@@ -221,9 +221,6 @@
WorldMercatorProjection.cs
-
- Animatable.WinUI.cs
-
DependencyPropertyHelper.WinUI.cs
@@ -263,6 +260,9 @@
Matrix.WinUI.cs
+
+ OpacityHelper.WinUI.cs
+
Point.WinUI.cs
diff --git a/MapControl/WPF/OpacityHelper.WPF.cs b/MapControl/WPF/OpacityHelper.WPF.cs
new file mode 100644
index 00000000..daaee8c1
--- /dev/null
+++ b/MapControl/WPF/OpacityHelper.WPF.cs
@@ -0,0 +1,32 @@
+// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
+// Copyright © 2024 Clemens Fischer
+// Licensed under the Microsoft Public License (Ms-PL)
+
+using System;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media.Animation;
+
+namespace MapControl
+{
+ public static class OpacityHelper
+ {
+ public static async Task SwapOpacities(UIElement topElement, UIElement bottomElement)
+ {
+ topElement.BeginAnimation(UIElement.OpacityProperty, new DoubleAnimation
+ {
+ To = 1d,
+ Duration = MapBase.ImageFadeDuration
+ });
+
+ bottomElement.BeginAnimation(UIElement.OpacityProperty, new DoubleAnimation
+ {
+ To = 0d,
+ BeginTime = MapBase.ImageFadeDuration,
+ Duration = TimeSpan.Zero
+ });
+
+ await Task.CompletedTask;
+ }
+ }
+}
diff --git a/MapControl/WinUI/Animatable.WinUI.cs b/MapControl/WinUI/Animatable.WinUI.cs
deleted file mode 100644
index f892810e..00000000
--- a/MapControl/WinUI/Animatable.WinUI.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
-// Copyright © 2024 Clemens Fischer
-// Licensed under the Microsoft Public License (Ms-PL)
-
-#if WINUI
-using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Media.Animation;
-#else
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Media.Animation;
-#endif
-
-namespace MapControl
-{
- internal static class Animatable
- {
- public static void BeginAnimation(this DependencyObject obj, string property, Timeline animation)
- {
- Storyboard.SetTargetProperty(animation, property);
- Storyboard.SetTarget(animation, obj);
-
- var storyboard = new Storyboard();
- storyboard.Children.Add(animation);
- storyboard.Begin();
- }
-
- public static void BeginAnimation(this DependencyObject obj, DependencyProperty property, Timeline animation)
- {
- if (animation != null && property == UIElement.OpacityProperty)
- {
- BeginAnimation(obj, nameof(UIElement.Opacity), animation);
- }
- }
- }
-}
diff --git a/MapControl/WinUI/MapBase.WinUI.cs b/MapControl/WinUI/MapBase.WinUI.cs
index ff42c963..e86fcc8f 100644
--- a/MapControl/WinUI/MapBase.WinUI.cs
+++ b/MapControl/WinUI/MapBase.WinUI.cs
@@ -175,7 +175,7 @@ namespace MapControl
centerAnimation.Completed += CenterAnimationCompleted;
- this.BeginAnimation(nameof(AnimatedCenter), centerAnimation);
+ BeginAnimation(nameof(AnimatedCenter), centerAnimation);
}
}
}
@@ -270,7 +270,7 @@ namespace MapControl
zoomLevelAnimation.Completed += ZoomLevelAnimationCompleted;
- this.BeginAnimation(nameof(ZoomLevel), zoomLevelAnimation);
+ BeginAnimation(nameof(ZoomLevel), zoomLevelAnimation);
}
}
}
@@ -346,7 +346,7 @@ namespace MapControl
headingAnimation.Completed += HeadingAnimationCompleted;
- this.BeginAnimation(nameof(Heading), headingAnimation);
+ BeginAnimation(nameof(Heading), headingAnimation);
}
}
}
@@ -362,5 +362,15 @@ namespace MapControl
headingAnimation = null;
}
}
+
+ public void BeginAnimation(string property, Timeline animation)
+ {
+ Storyboard.SetTarget(animation, this);
+ Storyboard.SetTargetProperty(animation, property);
+
+ var storyboard = new Storyboard();
+ storyboard.Children.Add(animation);
+ storyboard.Begin();
+ }
}
}
diff --git a/MapControl/WinUI/OpacityHelper.WinUI.cs b/MapControl/WinUI/OpacityHelper.WinUI.cs
new file mode 100644
index 00000000..9bfed25c
--- /dev/null
+++ b/MapControl/WinUI/OpacityHelper.WinUI.cs
@@ -0,0 +1,47 @@
+// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
+// Copyright © 2024 Clemens Fischer
+// Licensed under the Microsoft Public License (Ms-PL)
+
+using System;
+using System.Threading.Tasks;
+#if WINUI
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Media.Animation;
+#else
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Media.Animation;
+#endif
+
+namespace MapControl
+{
+ public static class OpacityHelper
+ {
+ public static void BeginOpacityAnimation(DependencyObject obj, DoubleAnimation animation)
+ {
+ Storyboard.SetTargetProperty(animation, nameof(UIElement.Opacity));
+ Storyboard.SetTarget(animation, obj);
+
+ var storyboard = new Storyboard();
+ storyboard.Children.Add(animation);
+ storyboard.Begin();
+ }
+
+ public static async Task SwapOpacities(UIElement topElement, UIElement bottomElement)
+ {
+ BeginOpacityAnimation(topElement, new DoubleAnimation
+ {
+ To = 1d,
+ Duration = MapBase.ImageFadeDuration
+ });
+
+ BeginOpacityAnimation(bottomElement, new DoubleAnimation
+ {
+ To = 0d,
+ BeginTime = MapBase.ImageFadeDuration,
+ Duration = TimeSpan.Zero
+ });
+
+ await Task.CompletedTask;
+ }
+ }
+}
diff --git a/MapControl/WinUI/Tile.WinUI.cs b/MapControl/WinUI/Tile.WinUI.cs
index 71202b61..7bfc84d8 100644
--- a/MapControl/WinUI/Tile.WinUI.cs
+++ b/MapControl/WinUI/Tile.WinUI.cs
@@ -18,7 +18,7 @@ namespace MapControl
{
private void BeginOpacityAnimation()
{
- Image.BeginAnimation(UIElement.OpacityProperty,
+ OpacityHelper.BeginOpacityAnimation(Image,
new DoubleAnimation
{
From = 0d,