diff --git a/samples/RenderDemo/Pages/TransitionsPage.xaml b/samples/RenderDemo/Pages/TransitionsPage.xaml
index ce5db380c0..1985074b0f 100644
--- a/samples/RenderDemo/Pages/TransitionsPage.xaml
+++ b/samples/RenderDemo/Pages/TransitionsPage.xaml
@@ -145,7 +145,7 @@
+
+
+
+
@@ -181,6 +201,7 @@
+
diff --git a/src/Avalonia.Visuals/Animation/Transitions/BrushTransition.cs b/src/Avalonia.Visuals/Animation/Transitions/BrushTransition.cs
index 0f7501e279..8d0b9089f9 100644
--- a/src/Avalonia.Visuals/Animation/Transitions/BrushTransition.cs
+++ b/src/Avalonia.Visuals/Animation/Transitions/BrushTransition.cs
@@ -1,29 +1,67 @@
using System;
using Avalonia.Animation.Animators;
+using Avalonia.Animation.Easings;
using Avalonia.Media;
+#nullable enable
+
namespace Avalonia.Animation
{
///
/// Transition class that handles with type.
- /// Only values of will correctly transition.
+ /// Only values of will transition correctly at the moment.
///
- public class ISolidColorBrushTransition : Transition
+ public class BrushTransition : Transition
{
private static readonly ISolidColorBrushAnimator s_animator = new ISolidColorBrushAnimator();
- public override IObservable DoTransition(IObservable progress, IBrush oldValue, IBrush newValue)
+ public override IObservable DoTransition(IObservable progress, IBrush? oldValue, IBrush? newValue)
+ {
+ var oldSolidColorBrush = TryGetSolidColorBrush(oldValue);
+ var newSolidColorBrush = TryGetSolidColorBrush(newValue);
+
+ if (oldSolidColorBrush != null && newSolidColorBrush != null)
+ {
+ EnsureImmutable(ref oldSolidColorBrush);
+ EnsureImmutable(ref newSolidColorBrush);
+
+ return new AnimatorTransitionObservable(
+ s_animator, progress, Easing, oldSolidColorBrush, newSolidColorBrush);
+ }
+
+ return new IncompatibleTransitionObservable(progress, Easing, oldValue, newValue);
+ }
+
+ private static void EnsureImmutable(ref ISolidColorBrush brush)
+ {
+ brush = (ISolidColorBrush)brush.ToImmutable();
+ }
+
+ private static ISolidColorBrush? TryGetSolidColorBrush(IBrush? brush)
{
- var oldSolidBrush = AsImmutable(oldValue);
- var newSolidBrush = AsImmutable(newValue);
+ if (brush is null)
+ {
+ return Brushes.Transparent;
+ }
- return new AnimatorTransitionObservable(
- s_animator, progress, Easing, oldSolidBrush, newSolidBrush);
+ return brush as ISolidColorBrush;
}
- private static ISolidColorBrush AsImmutable(IBrush brush)
+ private class IncompatibleTransitionObservable : TransitionObservableBase
{
- return (ISolidColorBrush)(brush as ISolidColorBrush)?.ToImmutable();
+ private readonly IBrush? _from;
+ private readonly IBrush? _to;
+
+ public IncompatibleTransitionObservable(IObservable progress, Easing easing, IBrush? from, IBrush? to) : base(progress, easing)
+ {
+ _from = @from;
+ _to = to;
+ }
+
+ protected override IBrush? ProduceValue(double progress)
+ {
+ return progress < 0.5 ? _from : _to;
+ }
}
}
}