using System; namespace Sonex.Client.Animations { using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Media.Animation; public static class OpacityPulse { private static readonly DependencyProperty PulseStoryboardProperty = DependencyProperty.RegisterAttached( "PulseStoryboard", typeof(Storyboard), typeof(OpacityPulse), new PropertyMetadata(null)); public static void Start(ButtonBase button) { Stop(button); var animation = new DoubleAnimation { From = 1, To = 0.4, Duration = TimeSpan.FromMilliseconds(600), AutoReverse = true, RepeatBehavior = RepeatBehavior.Forever }; var storyboard = new Storyboard(); Storyboard.SetTarget(animation, button); Storyboard.SetTargetProperty(animation, "Opacity"); storyboard.Children.Add(animation); RoutedEventHandler? handler = null; handler = (_, __) => { Stop(button); button.Click -= handler; }; button.Click += handler; button.SetValue(PulseStoryboardProperty, storyboard); storyboard.Begin(); } public static void Stop(ButtonBase button) { if (button.GetValue(PulseStoryboardProperty) is Storyboard sb) { sb.Stop(); button.Opacity = 1; button.ClearValue(PulseStoryboardProperty); } } } }